HTTP / cURL Reference
Pure HTTP examples for integrating ConsentKeys into any language or platform. Use these cURL commands to test and understand the OAuth flow.
Get your Client ID and Secret from the Developer Portal and configure your redirect URI (where users return to your app after authentication).
Quick Start
The complete OAuth 2.0 Authorization Code flow with PKCE:
# 1. Generate PKCE parameters
CODE_VERIFIER=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-43)
CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | openssl dgst -binary -sha256 | base64 | tr -d "=+/" | tr '/+' '_-')
STATE=$(openssl rand -hex 16)
# 2. Build authorization URL (open in browser)
CLIENT_ID="ck_your_client_id"
REDIRECT_URI="http://localhost:3000/callback" # Must match what you configured
AUTH_URL="https://pseudoidc.consentkeys.com/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=openid%20profile%20email&state=$STATE&code_challenge=$CODE_CHALLENGE&code_challenge_method=S256"
echo "Open this URL in your browser:"
echo "$AUTH_URL"
# 3. After authentication, you'll be redirected to:
# http://localhost:3000/callback?code=AUTH_CODE&state=STATE
# 4. Exchange code for tokens
AUTH_CODE="paste_code_from_redirect"
CLIENT_SECRET="your_client_secret"
curl -X POST https://pseudoidc.consentkeys.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=$AUTH_CODE" \
-d "redirect_uri=$REDIRECT_URI" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "code_verifier=$CODE_VERIFIER"
# 5. Get user info
ACCESS_TOKEN="paste_access_token_from_response"
curl https://pseudoidc.consentkeys.com/userinfo \
-H "Authorization: Bearer $ACCESS_TOKEN"
OIDC Discovery
Get OpenID Connect configuration:
curl https://pseudoidc.consentkeys.com/.well-known/openid-configuration
Response:
{
"issuer": "https://pseudoidc.consentkeys.com",
"authorization_endpoint": "https://pseudoidc.consentkeys.com/auth",
"token_endpoint": "https://pseudoidc.consentkeys.com/token",
"userinfo_endpoint": "https://pseudoidc.consentkeys.com/userinfo",
"jwks_uri": "https://pseudoidc.consentkeys.com/.well-known/jwks.json",
"introspection_endpoint": "https://pseudoidc.consentkeys.com/introspect",
"revocation_endpoint": "https://pseudoidc.consentkeys.com/revoke",
"response_types_supported": ["code"],
"subject_types_supported": ["public"],
"id_token_signing_alg_values_supported": ["RS256"],
"scopes_supported": ["openid", "profile", "email", "address"],
"grant_types_supported": ["authorization_code"],
"code_challenge_methods_supported": ["S256", "plain"]
}
:::info[Important Notes]
- **Grant Types**: The backend fully implements `client_credentials` flow but the discovery endpoint currently only advertises `authorization_code`. If you need machine-to-machine authentication, `client_credentials` is supported.
- **PKCE Methods**: Both `S256` (SHA-256) and `plain` are supported. **Use `S256` in production** for better security. The `plain` method should only be used in constrained environments.
:::
Get JWKS
Public keys for token verification:
curl https://pseudoidc.consentkeys.com/.well-known/jwks.json
Response:
{
"keys": [
{
"kty": "RSA",
"use": "sig",
"kid": "key-2024",
"n": "...",
"e": "AQAB",
"alg": "RS256"
}
]
}
Authorization Flow
Step 1: Generate PKCE Challenge
Bash:
# Generate code verifier (random 43-char string)
CODE_VERIFIER=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-43)
# Generate code challenge (SHA-256 hash of verifier)
CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | openssl dgst -binary -sha256 | base64 | tr -d "=+/" | tr '/+' '_-')
# Generate state for CSRF protection
STATE=$(openssl rand -hex 16)
echo "Code Verifier: $CODE_VERIFIER"
echo "Code Challenge: $CODE_CHALLENGE"
echo "State: $STATE"
Python:
import secrets
import hashlib
import base64
# Generate code verifier
code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).decode('utf-8').rstrip('=')
# Generate code challenge
digest = hashlib.sha256(code_verifier.encode('utf-8')).digest()
code_challenge = base64.urlsafe_b64encode(digest).decode('utf-8').rstrip('=')
# Generate state
state = secrets.token_urlsafe(16)
print(f"Code Verifier: {code_verifier}")
print(f"Code Challenge: {code_challenge}")
print(f"State: {state}")
JavaScript:
// Generate code verifier
function generateCodeVerifier() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return base64UrlEncode(array);
}
// Generate code challenge
async function generateCodeChallenge(verifier) {
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const hash = await crypto.subtle.digest('SHA-256', data);
return base64UrlEncode(new Uint8Array(hash));
}
function base64UrlEncode(array) {
return btoa(String.fromCharCode(...array))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
// Generate state
function generateState() {
return generateCodeVerifier().substring(0, 16);
}
Step 2: Authorization Request
Request:
GET /auth?response_type=code&client_id=ck_abc123&redirect_uri=http://localhost:3000/callback&scope=openid%20profile%20email&state=xyz789&code_challenge=CHALLENGE&code_challenge_method=S256 HTTP/1.1
Host: pseudoidc.consentkeys.com
cURL:
# This opens in a browser - construct the URL:
CLIENT_ID="ck_your_client_id"
REDIRECT_URI="https://pseudoidc.consentkeys.com/callback"
SCOPE="openid profile email"
STATE="your_random_state"
CODE_CHALLENGE="your_code_challenge"
# Open this URL in browser
echo "https://pseudoidc.consentkeys.com/auth?\
response_type=code&\
client_id=$CLIENT_ID&\
redirect_uri=$REDIRECT_URI&\
scope=$SCOPE&\
state=$STATE&\
code_challenge=$CODE_CHALLENGE&\
code_challenge_method=S256"
Response:
User will be redirected to:
https://pseudoidc.consentkeys.com/callback?code=AUTH_CODE_HERE&state=xyz789
Step 3: Token Exchange
Request:
POST /token HTTP/1.1
Host: pseudoidc.consentkeys.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=AUTH_CODE_HERE&
redirect_uri=http://localhost:3000/callback&
client_id=ck_abc123&
client_secret=SECRET_HERE&
code_verifier=CODE_VERIFIER_HERE
cURL:
curl -X POST https://pseudoidc.consentkeys.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTH_CODE" \
-d "redirect_uri=http://localhost:3000/callback" \
-d "client_id=ck_your_client_id" \
-d "client_secret=your_secret" \
-d "code_verifier=$CODE_VERIFIER"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "eyJhbGciOiJSUzI1NiIs...",
"scope": "openid profile email"
}
Step 4: Get User Info
Request:
GET /userinfo HTTP/1.1
Host: pseudoidc.consentkeys.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
cURL:
curl https://pseudoidc.consentkeys.com/userinfo \
-H "Authorization: Bearer $ACCESS_TOKEN"
Response:
{
"sub": "user_123abc",
"email": "user@example.com",
"email_verified": true,
"name": "John Doe",
"preferred_username": "johnd",
"picture": "https://cdn.consentkeys.com/avatars/..."
}
Token Introspection
Check if a token is valid:
Request:
POST /introspect HTTP/1.1
Host: pseudoidc.consentkeys.com
Content-Type: application/x-www-form-urlencoded
token=eyJhbGciOiJSUzI1NiIs...&
client_id=ck_abc123&
client_secret=SECRET_HERE
cURL:
curl -X POST https://pseudoidc.consentkeys.com/introspect \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=$ACCESS_TOKEN" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET"
Response:
{
"active": true,
"sub": "user_123abc",
"client_id": "ck_abc123",
"exp": 1703980800,
"iat": 1703977200,
"iss": "https://pseudoidc.consentkeys.com",
"scope": "openid profile email",
"token_type": "Bearer"
}
Token Revocation
Revoke an access token:
Request:
POST /revoke HTTP/1.1
Host: pseudoidc.consentkeys.com
Content-Type: application/x-www-form-urlencoded
token=eyJhbGciOiJSUzI1NiIs...&
client_id=ck_abc123&
client_secret=SECRET_HERE
cURL:
curl -X POST https://pseudoidc.consentkeys.com/revoke \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=$ACCESS_TOKEN" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET"
Response:
HTTP/1.1 200 OK
Client Credentials Flow
For machine-to-machine authentication:
Request:
POST /token HTTP/1.1
Host: pseudoidc.consentkeys.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&
client_id=ck_abc123&
client_secret=SECRET_HERE&
scope=openid
cURL:
curl -X POST https://pseudoidc.consentkeys.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "scope=openid"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid"
}
Error Responses
All endpoints return OAuth 2.0 error format:
{
"error": "invalid_request",
"error_description": "The redirect_uri parameter is required"
}
Common errors:
| Error | Description |
|---|---|
invalid_request | Missing required parameter |
invalid_client | Invalid client credentials |
invalid_grant | Authorization code expired/invalid |
unauthorized_client | Client not authorized for this action |
access_denied | User denied authorization |
invalid_scope | Requested scope not supported |
server_error | Internal server error |
too_many_requests | Rate limit exceeded |
Complete Shell Script
#!/bin/bash
# Configuration
CLIENT_ID="ck_your_client_id"
CLIENT_SECRET="your_client_secret"
REDIRECT_URI="https://pseudoidc.consentkeys.com/callback"
BASE_URL="https://pseudoidc.consentkeys.com"
# Generate PKCE
CODE_VERIFIER=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-43)
CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | openssl dgst -binary -sha256 | base64 | tr -d "=+/" | tr '/+' '_-')
STATE=$(openssl rand -hex 16)
# Build auth URL
AUTH_URL="$BASE_URL/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=openid%20profile%20email&state=$STATE&code_challenge=$CODE_CHALLENGE&code_challenge_method=S256"
echo "1. Open this URL in your browser:"
echo "$AUTH_URL"
echo ""
echo "2. After authentication, paste the 'code' parameter from the redirect URL:"
read -r AUTH_CODE
echo ""
echo "3. Exchanging code for tokens..."
# Exchange code for tokens
TOKEN_RESPONSE=$(curl -s -X POST "$BASE_URL/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=$AUTH_CODE" \
-d "redirect_uri=$REDIRECT_URI" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "code_verifier=$CODE_VERIFIER")
echo "$TOKEN_RESPONSE" | jq '.'
# Extract access token
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')
echo ""
echo "4. Getting user info..."
# Get user info
curl -s "$BASE_URL/userinfo" \
-H "Authorization: Bearer $ACCESS_TOKEN" | jq '.'
Language Examples
Go
package main
import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"fmt"
"net/http"
"net/url"
)
func generatePKCE() (string, string) {
// Generate verifier
b := make([]byte, 32)
rand.Read(b)
verifier := base64.RawURLEncoding.EncodeToString(b)
// Generate challenge
h := sha256.New()
h.Write([]byte(verifier))
challenge := base64.RawURLEncoding.EncodeToString(h.Sum(nil))
return verifier, challenge
}
func main() {
verifier, challenge := generatePKCE()
params := url.Values{}
params.Add("response_type", "code")
params.Add("client_id", "ck_your_client_id")
params.Add("redirect_uri", "https://pseudoidc.consentkeys.com/callback")
params.Add("scope", "openid profile email")
params.Add("code_challenge", challenge)
params.Add("code_challenge_method", "S256")
authURL := "https://pseudoidc.consentkeys.com/auth?" + params.Encode()
fmt.Println(authURL)
}
Ruby
require 'securerandom'
require 'digest'
require 'base64'
require 'uri'
require 'net/http'
require 'json'
# Generate PKCE
code_verifier = Base64.urlsafe_encode64(SecureRandom.random_bytes(32), padding: false)
code_challenge = Base64.urlsafe_encode64(Digest::SHA256.digest(code_verifier), padding: false)
# Build auth URL
params = {
response_type: 'code',
client_id: 'ck_your_client_id',
redirect_uri: 'https://pseudoidc.consentkeys.com/callback',
scope: 'openid profile email',
code_challenge: code_challenge,
code_challenge_method: 'S256'
}
auth_url = "https://pseudoidc.consentkeys.com/auth?#{URI.encode_www_form(params)}"
puts auth_url
PHP
<?php
function generateCodeVerifier() {
return rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');
}
function generateCodeChallenge($verifier) {
return rtrim(strtr(base64_encode(hash('sha256', $verifier, true)), '+/', '-_'), '=');
}
$codeVerifier = generateCodeVerifier();
$codeChallenge = generateCodeChallenge($codeVerifier);
$params = http_build_query([
'response_type' => 'code',
'client_id' => 'ck_your_client_id',
'redirect_uri' => 'https://pseudoidc.consentkeys.com/callback',
'scope' => 'openid profile email',
'code_challenge' => $codeChallenge,
'code_challenge_method' => 'S256',
]);
$authUrl = "https://pseudoidc.consentkeys.com/auth?{$params}";
echo $authUrl;
?>
Next Steps
- Learn about OAuth concepts
- Understand scopes and claims
- Check error codes