OAuth 2.0 / OIDC
Use Tiquo as an OAuth 2.0 Authorization Server and OpenID Connect Provider
OAuth 2.0 / OIDC
Tiquo acts as a full OAuth 2.0 Authorization Server and OpenID Connect (OIDC) Provider. This lets you integrate customer authentication using the standard authorization code flow, which works with native mobile apps, server-side applications, and any platform that supports OAuth.
After a customer completes the OAuth flow, Tiquo issues JWT access tokens that work with the Client API, just like tokens from the DOM Package.
Endpoints
| Endpoint | URL | Description |
|---|---|---|
| Discovery | https://edge.tiquo.app/.well-known/openid-configuration | OIDC discovery metadata |
| OAuth Metadata | https://edge.tiquo.app/.well-known/oauth-authorization-server | OAuth 2.0 server metadata |
| Authorization | https://edge.tiquo.app/api/auth/oauth2/authorize | Start the authorization flow |
| Token | https://edge.tiquo.app/api/auth/oauth2/token | Exchange code for tokens |
| UserInfo | https://edge.tiquo.app/api/auth/oauth2/userinfo | Get user claims |
| JWKS | https://edge.tiquo.app/api/oauth2/jwks | Public keys for token verification |
| Client Registration | https://edge.tiquo.app/api/auth/oauth2/register | Dynamic client registration |
Setup
1. Register an OAuth Client
You can register an OAuth client through the Tiquo dashboard or using the dynamic client registration endpoint.
Through the dashboard:
- Go to Settings > OAuth Clients
- Click Create OAuth Client
- Enter a name, redirect URI(s), and any other required settings
- Copy the
client_idandclient_secret
Through the API (dynamic registration):
curl -X POST "https://edge.tiquo.app/api/auth/oauth2/register" \
-H "Content-Type: application/json" \
-d '{
"client_name": "My Mobile App",
"redirect_uris": ["myapp://callback"],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"token_endpoint_auth_method": "client_secret_post"
}'2. Authorization Flow
Redirect the customer to the authorization endpoint:
https://edge.tiquo.app/api/auth/oauth2/authorize?
client_id=your_client_id
&response_type=code
&redirect_uri=https://yourapp.com/callback
&scope=openid profile email
&state=random_state_value
&code_challenge=your_code_challenge
&code_challenge_method=S256| Parameter | Required | Description |
|---|---|---|
client_id | Yes | Your OAuth client ID |
response_type | Yes | Must be code |
redirect_uri | Yes | Where to redirect after authentication |
scope | No | Space-separated list of scopes |
state | Recommended | Random value for CSRF protection |
code_challenge | Recommended | PKCE code challenge (S256 method) |
code_challenge_method | Recommended | Must be S256 when using PKCE |
The customer will see a sign-in page where they authenticate with their email (via OTP). After authentication, Tiquo redirects back to your redirect_uri with an authorization code:
https://yourapp.com/callback?code=auth_code_here&state=random_state_value3. Exchange Code for Tokens
Exchange the authorization code for tokens:
curl -X POST "https://edge.tiquo.app/api/auth/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=auth_code_here" \
-d "redirect_uri=https://yourapp.com/callback" \
-d "client_id=your_client_id" \
-d "client_secret=your_client_secret" \
-d "code_verifier=your_code_verifier"Response:
{
"access_token": "eyJhbGciOiJSUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "rt_xxx...",
"id_token": "eyJhbGciOiJSUzI1NiJ9...",
"scope": "openid profile email"
}4. Use the Access Token
The access token works with all Client API endpoints:
curl -X GET "https://edge.tiquo.app/api/client/v1/profile" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..."Supported Grant Types
| Grant Type | Description |
|---|---|
authorization_code | Standard authorization code flow (with optional PKCE) |
refresh_token | Exchange a refresh token for new tokens |
Scopes
| Scope | Description |
|---|---|
openid | Required for OIDC. Returns an ID token. |
profile | Includes name and profile information in the ID token |
email | Includes email address in the ID token |
PKCE Support
Tiquo supports Proof Key for Code Exchange (PKCE) using the S256 challenge method. PKCE is recommended for all clients and is required for public clients (like mobile apps and single-page applications) that cannot securely store a client secret.
To use PKCE:
- Generate a random
code_verifier(43-128 characters, URL-safe) - Compute the
code_challengeas the Base64-URL-encoded SHA-256 hash of the verifier - Include
code_challengeandcode_challenge_method=S256in the authorization request - Include the original
code_verifierin the token exchange request
Token Refresh
To get a new access token using a refresh token:
curl -X POST "https://edge.tiquo.app/api/auth/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=rt_xxx..." \
-d "client_id=your_client_id" \
-d "client_secret=your_client_secret"Refresh tokens are rotated on each use. Always store and use the new refresh token from the response.
UserInfo Endpoint
Retrieve the authenticated user's claims:
curl -X GET "https://edge.tiquo.app/api/auth/oauth2/userinfo" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..."Response:
{
"sub": "user_abc123",
"email": "customer@example.com",
"name": "John Doe"
}JWKS (Token Verification)
To verify JWT tokens yourself, fetch the public keys from the JWKS endpoint:
curl "https://edge.tiquo.app/api/oauth2/jwks"The response contains the RSA public key(s) in JWK format. Tokens are signed with RS256.
Token Details
| Token | Algorithm | Lifetime | Issuer | Audience |
|---|---|---|---|---|
| Access token | RS256 | 1 hour | https://auth.tiquo.app | tiquo-client-api |
| ID token | RS256 | 10 hours | https://auth.tiquo.app | Your client ID |
| Refresh token | N/A | 30 days | N/A | N/A |
Access Token Claims
{
"sub": "user_abc123",
"email": "customer@example.com",
"token_source": "oauth",
"organization_id": "org_xyz",
"org_customer_id": "cust_456",
"customer_number": "CUST-000001",
"client_id": "your_client_id",
"scope": "openid profile email",
"iss": "https://auth.tiquo.app",
"aud": "tiquo-client-api",
"exp": 1706580000,
"iat": 1706576400
}Note that OAuth tokens include the client_id and scope claims, which are not present in DOM Package tokens.
ID Token Claims
The ID token (returned when the openid scope is requested) may include additional customer-level information, such as the customer's name and spending data, depending on the scopes requested.
Native Mobile App Integration
iOS (Swift)
Use ASWebAuthenticationSession to handle the OAuth flow in iOS:
import AuthenticationServices
let authURL = URL(string: "https://edge.tiquo.app/api/auth/oauth2/authorize?client_id=\(clientId)&response_type=code&redirect_uri=myapp://callback&scope=openid%20profile%20email&code_challenge=\(codeChallenge)&code_challenge_method=S256")!
let session = ASWebAuthenticationSession(
url: authURL,
callbackURLScheme: "myapp"
) { callbackURL, error in
guard let url = callbackURL,
let code = URLComponents(url: url, resolvingAgainstBaseURL: false)?
.queryItems?.first(where: { $0.name == "code" })?.value
else { return }
// Exchange the code for tokens
exchangeCodeForTokens(code: code, codeVerifier: codeVerifier)
}
session.presentationContextProvider = self
session.start()Android (Kotlin)
Use Custom Tabs or AppAuth for the OAuth flow:
val authUri = Uri.parse("https://edge.tiquo.app/api/auth/oauth2/authorize")
.buildUpon()
.appendQueryParameter("client_id", clientId)
.appendQueryParameter("response_type", "code")
.appendQueryParameter("redirect_uri", "myapp://callback")
.appendQueryParameter("scope", "openid profile email")
.appendQueryParameter("code_challenge", codeChallenge)
.appendQueryParameter("code_challenge_method", "S256")
.build()
val customTabsIntent = CustomTabsIntent.Builder().build()
customTabsIntent.launchUrl(context, authUri)How It Works with the Client API
The OAuth flow issues the same type of JWT access tokens as the DOM Package. Once you have an access token, you use it with the Client API in exactly the same way:
- Register an OAuth client and configure redirect URIs
- Redirect the customer to the authorization endpoint
- The customer signs in (via email OTP on the Tiquo sign-in page)
- Tiquo redirects back to your app with an authorization code
- Your app exchanges the code for an access token and refresh token
- Use the access token with Client API endpoints (
/profile,/orders,/bookings,/enquiries) - When the access token expires, use the refresh token to get a new pair
The key difference from the DOM Package is that OAuth uses a redirect-based flow, while the DOM Package handles everything in-page. Choose based on your platform and requirements.