Tiquo
API and AuthenticationCustomer AuthenticationOAuth / OIDC

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

EndpointURLDescription
Discoveryhttps://edge.tiquo.app/.well-known/openid-configurationOIDC discovery metadata
OAuth Metadatahttps://edge.tiquo.app/.well-known/oauth-authorization-serverOAuth 2.0 server metadata
Authorizationhttps://edge.tiquo.app/api/auth/oauth2/authorizeStart the authorization flow
Tokenhttps://edge.tiquo.app/api/auth/oauth2/tokenExchange code for tokens
UserInfohttps://edge.tiquo.app/api/auth/oauth2/userinfoGet user claims
JWKShttps://edge.tiquo.app/api/oauth2/jwksPublic keys for token verification
Client Registrationhttps://edge.tiquo.app/api/auth/oauth2/registerDynamic 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:

  1. Go to Settings > OAuth Clients
  2. Click Create OAuth Client
  3. Enter a name, redirect URI(s), and any other required settings
  4. Copy the client_id and client_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
ParameterRequiredDescription
client_idYesYour OAuth client ID
response_typeYesMust be code
redirect_uriYesWhere to redirect after authentication
scopeNoSpace-separated list of scopes
stateRecommendedRandom value for CSRF protection
code_challengeRecommendedPKCE code challenge (S256 method)
code_challenge_methodRecommendedMust 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_value

3. 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 TypeDescription
authorization_codeStandard authorization code flow (with optional PKCE)
refresh_tokenExchange a refresh token for new tokens

Scopes

ScopeDescription
openidRequired for OIDC. Returns an ID token.
profileIncludes name and profile information in the ID token
emailIncludes 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:

  1. Generate a random code_verifier (43-128 characters, URL-safe)
  2. Compute the code_challenge as the Base64-URL-encoded SHA-256 hash of the verifier
  3. Include code_challenge and code_challenge_method=S256 in the authorization request
  4. Include the original code_verifier in 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

TokenAlgorithmLifetimeIssuerAudience
Access tokenRS2561 hourhttps://auth.tiquo.apptiquo-client-api
ID tokenRS25610 hourshttps://auth.tiquo.appYour client ID
Refresh tokenN/A30 daysN/AN/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:

  1. Register an OAuth client and configure redirect URIs
  2. Redirect the customer to the authorization endpoint
  3. The customer signs in (via email OTP on the Tiquo sign-in page)
  4. Tiquo redirects back to your app with an authorization code
  5. Your app exchanges the code for an access token and refresh token
  6. Use the access token with Client API endpoints (/profile, /orders, /bookings, /enquiries)
  7. 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.

On this page