Login with TTAR
Authorization with a TTAR account on your website or app: players sign in with one click, and you see their rating right away.
If you run a website or an app for table tennis players — a club, tournaments, coaching, an equipment shop — add “Login with TTAR”. Players will be able to sign in to your service with their TTAR account in one click, just like with Google or Telegram, without a new username and password. And you immediately learn who has come to you and how strong a player they are.
What it gives your service:
- More sign-ups. No forms to fill in and no email to confirm: players log in with their TTAR login, so fewer people abandon the registration halfway.
- The player's rating right away. Together with the authorization you receive the TTAR rating: use it to seed a tournament, split participants into groups by strength, find a sparring partner or check eligibility for a competition.
- No authorization of your own to build. Password storage, account recovery, sign-in with Google and Telegram — TTAR already does all of that. Your developers only need to connect the standard OpenID Connect protocol, with ready-made libraries for every popular programming language.
- Safe for players. You never receive the TTAR password: players enter it only on the TTAR page. You get only the data you asked for — the player ID, name and avatar, email and rating.
Below is the technical description. You can pass this page straight to your developers.
Authorization server endpoints
Most OIDC libraries only need the Issuer: they read the other addresses from the discovery document.
Issuer https://stage.api.ttar.app Discovery https://stage.api.ttar.app/.well-known/openid-configuration Authorization https://stage.api.ttar.app/connect/authorize Token https://stage.api.ttar.app/connect/token UserInfo https://stage.api.ttar.app/connect/userinfo End session https://stage.api.ttar.app/connect/logout JWKS https://stage.api.ttar.app/.well-known/jwks
Client registration
Each partner receives a client_id. There is no client secret — only PKCE (code_challenge_method=S256) is supported. To register, write to us at kot@ttar.app.
During registration you provide one or more redirect_uri values — the URLs in your application where we will redirect the user after authorization. We add them to a whitelist. In each request you specify the exact URI you want to use, and the server validates it against that list.
Optionally you also provide one or more post_logout_redirect_uri values — where we send the user back after a logout through our end-session endpoint /connect/logout (see “Logout” below). This is a separate whitelist: a redirect_uri is not accepted as a post-logout target. You only need it if you use that logout.
Sign-in: Authorization Code + PKCE
Step 1. Redirect the user to the authorization endpoint. Build the URL below and navigate the user's browser to it as a full page navigation, not an iframe:
GET https://stage.api.ttar.app/connect/authorize ?client_id=YOUR_CLIENT_ID &response_type=code &redirect_uri=https://yourapp.com/callback &scope=openid profile email ttar:rating &code_challenge=BASE64URL(SHA256(code_verifier)) &code_challenge_method=S256 &state=RANDOM_OPAQUE_VALUE
If the user is not signed in to TTAR in this browser yet, they see the TTAR login page and sign in. If they already have an active TTAR session, the login page is skipped and the code is issued right away (single sign-on) — unless you ask for a fresh login with prompt=login. The optional prompt and max_age parameters are described in “Re-authentication and account switching” below.
Step 2. Receive the response at your redirect_uri. After a successful login the browser is automatically redirected to your redirect_uri with two query parameters:
GET https://yourapp.com/callback?code=AUTHORIZATION_CODE&state=RANDOM_OPAQUE_VALUE
code— a one-time authorization code. It is valid for about 60 seconds, so exchange it immediately.state— the same value you sent in step 1. Always verify it matches what you stored on your side: this protects against CSRF.
If the user denied access or an error occurred, you get:
GET https://yourapp.com/callback?error=access_denied&error_description=...&state=...
Step 3. Exchange the code for tokens. From your server, not the browser, send a POST with the code from step 2:
POST https://stage.api.ttar.app/connect/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &client_id=YOUR_CLIENT_ID &code=AUTHORIZATION_CODE &redirect_uri=https://yourapp.com/callback &code_verifier=YOUR_CODE_VERIFIER
redirect_uri here must match exactly what was sent in step 1: the server uses it as an additional binding check.Response:
{
"access_token": "...",
"id_token": "...",
"refresh_token": "...",
"token_type": "Bearer",
"expires_in": 3600
}
access_token— a Bearer token for API calls, including/connect/userinfo. It is a JWT signed with RS256.id_token— a JWT with basic user identity:sub, name, email, etc. Verify its signature before trusting it.refresh_token— to obtain new tokens without asking the user to log in again. Issued only when you requested theoffline_accessscope.
Step 4. Refresh tokens. When the access token expires, get new tokens with the refresh token:
POST https://stage.api.ttar.app/connect/token Content-Type: application/x-www-form-urlencoded grant_type=refresh_token &client_id=YOUR_CLIENT_ID &refresh_token=REFRESH_TOKEN
Scopes
| Scope | Returns |
|---|---|
openid | sub (the TTAR player ID). Required. |
profile | name, picture (avatar URL) |
email | email, email_verified |
offline_access | Adds a refresh_token to the response of the token endpoint /connect/token. Without this scope no refresh token is issued. |
ttar:rating | The ttar_rating claim in the access token — an array of the player's ratings (see below). |
The ttar_rating claim
When ttar:rating is requested and the player has a rating, the access token contains a ttar_rating claim. It is a JSON array with one entry per hand — the main and the weak one:
[
{
"handType": "Main",
"rating": 1456,
"games": 120,
"qualificationPoints": 85,
"isRated": true
},
{
"handType": "Weak",
"rating": 1102,
"games": 15,
"qualificationPoints": 10,
"isRated": false
}
]
Additional user fields (name, avatar, email) are available from the UserInfo endpoint /connect/userinfo or inside the id_token.
Re-authentication and account switching
TTAR keeps a single sign-on (SSO) session in the user's browser — a cookie on the TTAR API domain. While it is active, /connect/authorize returns a code for the same TTAR user without showing the login page. This session is independent of your application's session: logging the user out of your app does not end it.
prompt=login— always shows the TTAR login page and makes the user sign in again, even with an active session: an existing TTAR session is never reused. The user may sign in with a different TTAR account. Recommended for account linking.prompt=select_account— same asprompt=login. TTAR has no account picker: the user chooses the account by signing in with it.prompt=none— never shows any UI. Without an active session, or with one older thanmax_age, the user is sent back to yourredirect_uriwitherror=login_required.prompt=consent— accepted, has no effect: registered partners are pre-approved, TTAR shows no consent screen.max_age=N— if the user signed in more thanNseconds ago, they must sign in again.max_age=0is the same asprompt=login.
An invalid prompt (an unknown value, or none combined with another value) is rejected with HTTP 400 on the TTAR side — the browser is not redirected back to your redirect_uri.
The auth_time claim. The id_token contains auth_time — the Unix time in seconds of the user's last interactive sign-in to TTAR: email and password, Google or Telegram. It stays unchanged when tokens are refreshed. It may be missing only for TTAR sessions started before this feature was released. Such a session never satisfies prompt=login or max_age and is always re-established, so when you send either parameter the id_token always contains auth_time.
Linking a TTAR account:
- Add
prompt=loginto the authorization request and remember when you started it. - After exchanging the code, verify that
auth_timeis not earlier than that moment, allowing a few seconds of clock skew. This confirms the user actually signed in during this request rather than an existing session being reused. - Link on
sub— the TTAR player ID.
auth_time reflects it.You do not need a logout to let the user link a different TTAR account — prompt=login is enough.
Logout
Logging the user out of your application does not end their TTAR session. If you also want to end it in this browser (for example “sign out everywhere” or a shared computer), send the user's browser to the end-session endpoint /connect/logout as a full-page navigation. An XHR or an iframe will not work: the session cookie belongs to the TTAR domain.
GET https://stage.api.ttar.app/connect/logout ?client_id=YOUR_CLIENT_ID &post_logout_redirect_uri=https://yourapp.com/logged-out &state=RANDOM_OPAQUE_VALUE &id_token_hint=ID_TOKEN
- TTAR deletes its session cookie and redirects the browser to
post_logout_redirect_uriwithstateappended. post_logout_redirect_urimust be registered in advance. The match is exact, and it is a separate list fromredirect_uri(see “Client registration”). An unregistered value makes TTAR reject the whole request with HTTP 400 — and the session is not ended.- Without
post_logout_redirect_urithe session is ended, but the user is not returned to your application. id_token_hintis optional. If you send it, it must be anid_tokenissued to yourclient_id. An expired one is fine.- This ends the user's TTAR session in this browser for every service that has “Login with TTAR”, not only yours.
Token validation
Tokens are signed with RS256. Public keys are available at the standard JWKS URL:
https://stage.api.ttar.app/.well-known/jwks
Any standard OIDC library will pick them up automatically via the discovery endpoint. Verify:
- the signature:
alg=RS256, key from JWKS; iss=https://stage.api.ttar.app;aud= yourclient_id;exp: the token has not expired;auth_time, when you useprompt=loginormax_age(see “The auth_time claim” above).
Staging notes
- Staging is a test environment for your experiments.
- A test account will be provided separately.
- When moving to production, your
client_idstays the same — only the Issuer changes, tohttps://api.ttar.app.