Authorization Code Grant Flow
The Authorization Code Grant Flow is the recommended OAuth 2.0 flow for server-side web applications that need to access the eventOne API on behalf of a user. It involves exchanging a short-lived authorization code for a longer-lived access token.
PKCE (Proof Key for Code Exchange, RFC 7636) with the S256 challenge method is required for all authorization requests.
Prerequisites
Before starting, you'll need:
- An Application ID and Application Secret — obtained by registering your application in the eventOne dashboard.
- A redirect URI — the URL in your application that eventOne will redirect users to after authorization.
Generate a PKCE code verifier and challenge
Before redirecting the user, generate a PKCE code_verifier and derive the code_challenge from it. The code_verifier is a cryptographically random string; the code_challenge is its Base64url-encoded SHA-256 hash.
# Generate a cryptographically random code_verifier (43–128 characters)
CODE_VERIFIER=$(openssl rand -base64 32 | tr -d '=' | tr '+/' '-_')
# Derive the code_challenge: SHA-256 hash, then Base64url-encode
CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr -d '=' | tr '+/' '-_')
Store the CODE_VERIFIER securely on the server — you will need it in Step 2.
Step 1: Redirect the user to the authorization URL
Send the user to the authorization endpoint, including the PKCE code_challenge and code_challenge_method. You can do this with a link or a server-side redirect:
https://api.event1.io/oauth/authorize?response_type=code&scope=openid%20api&client_id=APPLICATION_ID&redirect_uri=CALLBACK_URL&code_challenge=CODE_CHALLENGE&code_challenge_method=S256
<a href="https://api.event1.io/oauth/authorize?response_type=code&scope=openid%20api&client_id=APPLICATION_ID&redirect_uri=CALLBACK_URL&code_challenge=CODE_CHALLENGE&code_challenge_method=S256">
Sign in with eventOne
</a>
Query parameters:
| Parameter | Description |
|---|---|
response_type | Must be code. |
scope | Space-separated list of scopes. Use openid api to access the eventOne API. |
client_id | Your application's ID. |
redirect_uri | The URL to redirect back to after the user authorizes your application. Must match the registered redirect URI. |
code_challenge | The Base64url-encoded SHA-256 hash of your code_verifier. |
code_challenge_method | Must be S256. |
After the user approves the request, eventOne redirects them to your redirect_uri with a code query parameter:
https://your-app.example.com/callback?code=AUTHORIZATION_CODE
Step 2: Exchange the code for an access token
Use the authorization code received in the redirect — along with the code_verifier from the PKCE step — to request an access token:
export APPLICATION_ID="..."
export APPLICATION_SECRET="..."
export REDIRECT_URI="..."
export AUTHORIZATION_CODE="..."
# CODE_VERIFIER must be the same value generated before Step 1
export CODE_VERIFIER="..."
curl --request POST \
--url 'https://api.event1.io/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "client_id=$APPLICATION_ID" \
--data-urlencode "client_secret=$APPLICATION_SECRET" \
--data-urlencode "redirect_uri=$REDIRECT_URI" \
--data-urlencode "code=$AUTHORIZATION_CODE" \
--data-urlencode "code_verifier=$CODE_VERIFIER"
A successful response returns a JSON object:
{
"access_token": "<ACCESS_TOKEN>",
"expires_in": 3600,
"id_token": "<ID_TOKEN>",
"scope": "openid api",
"token_type": "Bearer"
}
Response fields:
| Field | Description |
|---|---|
access_token | The token used to authenticate API requests. |
expires_in | Lifetime of the access token in seconds (1 hour). |
id_token | A JWT containing identity information about the authenticated user (OpenID Connect). |
scope | The scopes granted to the token. |
token_type | Always Bearer. |
Step 3: Call the API
Pass the access token in the Authorization header on requests to the GraphQL API:
curl --request POST \
--url https://api.event1.io/graphql \
--header 'Authorization: Bearer ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{"query": "{ viewer { id name } }"}'
Access tokens expire after 1 hour. When a token expires, restart the flow to obtain a new one.