Authorization Code Flow
Step-by-step walkthrough of the OAuth2 Authorization Code Grant flow.
The Authorization Code Grant is the only supported OAuth2 flow. It is designed for confidential clients (server-side applications) that can securely store a client secret.
Flow diagram
┌──────────┐ ┌───────────────┐ ┌──────────────────┐
│ Your App │ │ Vacation │ │ User's Browser │
│ (Server) │ │ Tracker API │ │ │
└────┬─────┘ └──────┬────────┘ └────────┬─────────┘
│ │ │
│ 1. Redirect user to /oauth/authorize │ │
│──────────────────────────────────────────>│ │
│ │ │
│ │ 2. Redirect to login/consent page │
│ │────────────────────────────────────────>│
│ │ │
│ │ 3. User logs in and grants permission │
│ │<────────────────────────────────────────│
│ │ │
│ 4. Redirect back with authorization code │ │
│<──────────────────────────────────────────│ │
│ │ │
│ 5. POST /oauth/token (exchange code) │ │
│──────────────────────────────────────────>│ │
│ │ │
│ 6. Return access_token, refresh_token │ │
│<──────────────────────────────────────────│ │
│ │ │
│ 7. GET /oauth/me (use access token) │ │
│──────────────────────────────────────────>│ │
│ │ │
│ 8. Return user profile │ │
│<──────────────────────────────────────────│ │Step 1: Redirect to authorization endpoint
Redirect the user's browser to the authorization endpoint with the required parameters:
GET https://api.app.vacationtracker.io/oauth/authorize
?client_id=your-client-id
&redirect_uri=https://yourapp.com/callback
&state=random-csrf-token
&scope=openid email profile
&response_type=code| Parameter | Required | Description |
|---|---|---|
client_id | Yes | Your registered OAuth client ID |
redirect_uri | Yes | Must exactly match a registered redirect URI for your client |
state | Yes | Random string for CSRF protection. You must verify this value when the user returns |
scope | No | Space-separated list of scopes. Defaults to openid |
response_type | No | Must be code. Defaults to code |
Step 2: User authenticates
The authorization endpoint validates your parameters and redirects the user to Vacation Tracker's login page. The user can authenticate via:
- Microsoft account
- Google account
- Slack account
- Email and password
Step 3: User grants permission
After authentication, the user sees a consent screen showing your application's name and the requested scopes. They can approve or deny the request.
Step 4: Receive authorization code
If the user approves, Vacation Tracker redirects back to your redirect_uri with an authorization code and your state value:
https://yourapp.com/callback?code=a1b2c3d4-e5f6-7890-abcd-ef1234567890&state=random-csrf-tokenImportant:
- Verify that the
stateparameter matches what you sent in Step 1 - The authorization code is single-use and expires after 10 minutes
Step 5: Exchange code for tokens
Make a server-side POST request to exchange the authorization code for tokens:
curl -X POST https://api.app.vacationtracker.io/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-d "redirect_uri=https://yourapp.com/callback" \
-d "client_id=your-client-id" \
-d "client_secret=your-client-secret"Or using HTTP Basic authentication:
curl -X POST https://api.app.vacationtracker.io/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "your-client-id:your-client-secret" \
-d "grant_type=authorization_code" \
-d "code=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-d "redirect_uri=https://yourapp.com/callback"Step 6: Receive tokens
On success, you receive a JSON response with your tokens:
{
"access_token": "eyJ...",
"id_token": "eyJ...",
"refresh_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600
}access_token: Use this to authenticate API requests. Expires in 60 minutes.id_token: Contains user identity claims. Expires in 60 minutes.refresh_token: Use this to get new access tokens. Valid for 365 days.
Step 7: Use the access token
Include the access token in the Authorization header when calling protected endpoints:
curl https://api.app.vacationtracker.io/oauth/me \
-H "Authorization: Bearer eyJ..."Refreshing tokens
When the access token expires, use the refresh token to get a new one:
curl -X POST https://api.app.vacationtracker.io/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=eyJ..." \
-d "client_id=your-client-id" \
-d "client_secret=your-client-secret"Response:
{
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600
}The same refresh token is returned — Vacation Tracker does not rotate refresh tokens.
Error handling
If something goes wrong, the authorization endpoint returns an error as a JSON response:
{
"error": "invalid_client",
"error_description": "Unknown client_id"
}See Endpoints for the complete list of error codes per endpoint.