Authentication

Klap uses OAuth 2.1 with the authorization code flow and PKCE. The user signs in with their Klap account and approves your app, and your app receives an access token to call the API on their behalf.

OAuth Endpoints

Klap’s authorization server is https://jcgvnoxzvxorflmpxjqv.supabase.co/auth/v1.

EndpointURL
Authorization server metadatahttps://jcgvnoxzvxorflmpxjqv.supabase.co/.well-known/oauth-authorization-server/auth/v1
Authorizationhttps://jcgvnoxzvxorflmpxjqv.supabase.co/auth/v1/oauth/authorize
Tokenhttps://jcgvnoxzvxorflmpxjqv.supabase.co/auth/v1/oauth/token
User infohttps://jcgvnoxzvxorflmpxjqv.supabase.co/auth/v1/oauth/userinfo
Dynamic client registrationhttps://jcgvnoxzvxorflmpxjqv.supabase.co/auth/v1/oauth/clients/register
Protected resource metadatahttps://api.klap.app/.well-known/oauth-protected-resource

The authorization server metadata (RFC 8414) lists these endpoints. The protected resource metadata (RFC 9728) points to the same authorization server, for clients that discover it from the API.

Clients

  • Clients are public. Klap issues no client secret. Use token_endpoint_auth_method: none, send your client_id in the body of token requests, and never send a client_secret.
  • PKCE is required on every authorization request, with code_challenge_method S256 (recommended) or plain.
  • Getting a client ID: Contact support@klap.app with your app’s name and redirect URIs, or register your app yourself with dynamic client registration (useful when each installation of your app has its own redirect URI).

Dynamic Client Registration

Registration is open and follows RFC 7591.

curl -X POST "https://jcgvnoxzvxorflmpxjqv.supabase.co/auth/v1/oauth/clients/register" \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "My App",
    "redirect_uris": ["https://example.com/oauth/callback"],
    "token_endpoint_auth_method": "none",
    "grant_types": ["authorization_code", "refresh_token"],
    "response_types": ["code"]
  }'

The response contains your client_id. The client_name is shown to users on the consent screen.

Scopes

Request openid email profile.

Scopes control what the user info endpoint returns. They don’t restrict the API: an access token can call every endpoint in this section on behalf of the user.

Authorization Flow

1. Create a PKCE Pair

Generate a random code_verifier (43 to 128 characters from A-Z, a-z, 0-9, -, ., _, ~) and derive the code_challenge from it: BASE64URL(SHA256(code_verifier)) without padding for S256.

CODE_VERIFIER=$(openssl rand -base64 64 | tr -d '\n=+/' | cut -c1-64)
CODE_CHALLENGE=$(printf '%s' "$CODE_VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr '+/' '-_' | tr -d '=\n')

Keep the code_verifier for step 3.

2. Send the User to the Authorization Endpoint

Redirect the user’s browser to the authorization endpoint:

https://jcgvnoxzvxorflmpxjqv.supabase.co/auth/v1/oauth/authorize
  ?response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=https%3A%2F%2Fexample.com%2Foauth%2Fcallback
  &scope=openid%20email%20profile
  &state=af0ifjsldkj
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256

(Shown on several lines for readability: send it as a single URL.)

Query Parameters

ParameterRequiredDescription
response_typeYesAlways code
client_idYesYour client ID
redirect_uriYesOne of your client’s registered redirect URIs
scopeYesopenid email profile
stateYesA random value you check when the user comes back (CSRF protection)
code_challengeYesThe PKCE code challenge from step 1
code_challenge_methodYesS256 (recommended) or plain

The user signs in to Klap (or creates an account), then sees Klap’s consent screen at https://klap.app/oauth/consent, titled “Connect your app’s name to Klap”. Once they approve, Klap redirects them to your redirect_uri:

https://example.com/oauth/callback?code=AUTHORIZATION_CODE&state=af0ifjsldkj

Check that state matches the value you sent. If the user declines, the redirect carries an error parameter instead of a code.

3. Exchange the Code for Tokens

Send a form-encoded POST to the token endpoint:

curl -X POST "https://jcgvnoxzvxorflmpxjqv.supabase.co/auth/v1/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "code=AUTHORIZATION_CODE" \
  --data-urlencode "redirect_uri=https://example.com/oauth/callback" \
  --data-urlencode "client_id=YOUR_CLIENT_ID" \
  --data-urlencode "code_verifier=YOUR_CODE_VERIFIER"

Response

{
  "access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6...",
  "token_type": "bearer",
  "expires_in": 3600,
  "refresh_token": "kZ3fQ9wR2tLm"
}

The response can include other standard OAuth fields. Store the access_token and the refresh_token.

4. Call the API

Send the access token in the Authorization header of every request to https://api.klap.app:

curl "https://api.klap.app/tasks?limit=5" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Refreshing Tokens

  • Access tokens expire after 1 hour (expires_in: 3600). Any endpoint called with an expired or invalid token returns HTTP 401. Refresh the token, then retry the request.
  • Refresh tokens rotate. Every refresh returns a new refresh_token, and each refresh token can be used only once. Always store the new refresh token, replacing the old one.
  • Reusing an old refresh token after a short grace period (about 10 seconds, to absorb concurrent retries) can revoke the connection, and the user then has to connect again.
curl -X POST "https://jcgvnoxzvxorflmpxjqv.supabase.co/auth/v1/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=refresh_token" \
  --data-urlencode "refresh_token=kZ3fQ9wR2tLm" \
  --data-urlencode "client_id=YOUR_CLIENT_ID"

The response has the same format as the code exchange. If the refresh fails (for example with invalid_grant), the connection is no longer valid: ask the user to reconnect their Klap account.

User Info

Use the user info endpoint to test a connection and to label it (for example with the user’s email).

Endpoint: GET https://jcgvnoxzvxorflmpxjqv.supabase.co/auth/v1/oauth/userinfo

Request

curl "https://jcgvnoxzvxorflmpxjqv.supabase.co/auth/v1/oauth/userinfo" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Response

{
  "sub": "5f1c2e9a-3b7d-4c8e-9f60-2a1b3c4d5e6f",
  "email": "jane@example.com"
}
  • sub (string): The user’s Klap ID. It matches author_id on Export Objects.
  • email (string): The user’s email address.

Other standard claims can be included, depending on the granted scopes.