API reference
Continue with SeleID (OIDC) API
All APIs · SDKs · Continue with SeleID (OIDC) · SeleStorage · SeleBase · Webhooks, queue, SeleMail, routing and push · SeleAI · SeleDomains search
Coming soon Version 1.0.0. OpenID Connect authorization-code flow with PKCE (S256) for outside apps. Public clients (mobile, browser) use no secret. Outside-app sign-in is switched on per environment; until then registered apps stay pending review.
Base URL
https://auth.seleid.dev SeleID issuer
Authentication and scopes
No API key. Public clients use the authorization code flow with PKCE (S256); confidential clients may also send a client secret. Scopes: openid, profile, email.
Rate limits and quotas
The token endpoint is rate limited per client and address; a limited call returns 429.
Endpoints
GET /.well-known/openid-configurationOpenID Connect discovery documentGET /.well-known/jwks.jsonPublic signing keys (JWKS)GET /authorizeStart sign-in (open in the system browser)POST /oauth/tokenExchange a code or refresh a tokenGET /oauth/userinfoProfile claims for the access tokenPOST /oauth/revokeRevoke a refresh or access token
GET /.well-known/openid-configuration
OpenID Connect discovery document
No authentication.
curl
curl -X GET "https://auth.seleid.dev/.well-known/openid-configuration"TypeScript
const res = await fetch('https://auth.seleid.dev/.well-known/openid-configuration', {
method: 'GET',
});
const data = await res.json();Python
import os, requests
res = requests.get(
"https://auth.seleid.dev/.well-known/openid-configuration"
)
print(res.status_code, res.text)
Example response
{
"issuer": "https://auth.seleid.dev",
"authorization_endpoint": "https://auth.seleid.dev/authorize",
"token_endpoint": "https://auth.seleid.dev/oauth/token",
"jwks_uri": "https://auth.seleid.dev/.well-known/jwks.json",
"response_types_supported": [
"code"
],
"code_challenge_methods_supported": [
"S256"
],
"scopes_supported": [
"openid",
"profile",
"email"
]
}
| Status | Meaning |
|---|---|
200 | Discovery document. |
GET /.well-known/jwks.json
Public signing keys (JWKS)
No authentication.
curl
curl -X GET "https://auth.seleid.dev/.well-known/jwks.json"TypeScript
const res = await fetch('https://auth.seleid.dev/.well-known/jwks.json', {
method: 'GET',
});
const data = await res.json();Python
import os, requests
res = requests.get(
"https://auth.seleid.dev/.well-known/jwks.json"
)
print(res.status_code, res.text)
| Status | Meaning |
|---|---|
200 | Key set. |
503 | Signing keys are not configured. |
POST /oauth/token
Exchange a code or refresh a token
No authentication.
curl
curl -X POST "https://auth.seleid.dev/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=authorization_code&code=CODE&redirect_uri=com.example.app%3A%2Fseleid&client_id=YOUR_CLIENT_ID&code_verifier=VERIFIER'TypeScript
const res = await fetch('https://auth.seleid.dev/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({"grant_type":"authorization_code","code":"CODE","redirect_uri":"com.example.app:/seleid","client_id":"YOUR_CLIENT_ID","code_verifier":"VERIFIER"}),
});
const data = await res.json();Python
import os, requests
res = requests.post(
"https://auth.seleid.dev/oauth/token",
data={
"grant_type": "authorization_code",
"code": "CODE",
"redirect_uri": "com.example.app:/seleid",
"client_id": "YOUR_CLIENT_ID",
"code_verifier": "VERIFIER",
}
)
print(res.status_code, res.text)
Example response
{
"access_token": "opaque",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "opaque",
"id_token": "eyJ…",
"scope": "openid profile email"
}
| Status | Meaning |
|---|---|
200 | Tokens. |
400 | invalid_request, invalid_grant, invalid_client or unsupported_grant_type. |
429 | Rate limited. |
GET /oauth/userinfo
Profile claims for the access token. Advertised only when outside-app sign-in is on.
Authentication: required.
curl
curl -X GET "https://auth.seleid.dev/oauth/userinfo" \
-H "Authorization: Bearer $ACCESS_TOKEN"TypeScript
const res = await fetch('https://auth.seleid.dev/oauth/userinfo', {
method: 'GET',
headers: { Authorization: `Bearer ${process.env.ACCESS_TOKEN}` },
});
const data = await res.json();Python
import os, requests
res = requests.get(
"https://auth.seleid.dev/oauth/userinfo",
headers={"Authorization": f"Bearer {os.environ['ACCESS_TOKEN']}"}
)
print(res.status_code, res.text)
Example response
{
"sub": "user_123",
"name": "Ada",
"email": "ada@example.com",
"email_verified": true
}
| Status | Meaning |
|---|---|
200 | Claims. |
401 | Invalid or expired token. |
POST /oauth/revoke
Revoke a refresh or access token. Advertised only when outside-app sign-in is on.
No authentication.
curl
curl -X POST "https://auth.seleid.dev/oauth/revoke" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'token=YOUR_TOKEN&client_id=YOUR_CLIENT_ID'TypeScript
const res = await fetch('https://auth.seleid.dev/oauth/revoke', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ token: "YOUR_TOKEN", client_id: "YOUR_CLIENT_ID" }),
});
const data = await res.json();Python
import os, requests
res = requests.post(
"https://auth.seleid.dev/oauth/revoke",
data={
"token": "YOUR_TOKEN",
"client_id": "YOUR_CLIENT_ID",
}
)
print(res.status_code, res.text)
| Status | Meaning |
|---|---|
200 | Revoked (also returned for unknown tokens). |
400 | Invalid request. |
The machine-readable OpenAPI 3.1 description for this API lives in the SeleID repository under docs/openapi/.