Authentication
Hookbase supports two authentication methods: JWT tokens and API keys.
JWT Tokens
JWT tokens are obtained by logging in and are used for browser-based access. Access tokens expire after 15 minutes; refresh tokens last 7 days.
Register
curl -X POST https://api.hookbase.app/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "your-password",
"displayName": "John Doe"
}'Response:
{
"user": {
"id": "usr_abc123",
"email": "[email protected]",
"displayName": "John Doe",
"emailVerified": false
},
"token": "eyJhbGciOiJIUzI1NiIs...",
"message": "Verification email sent"
}Email Verification
# Verify email with token from email link
curl -X POST https://api.hookbase.app/api/auth/verify-email \
-H "Content-Type: application/json" \
-d '{"token": "verification-token-from-email"}'# Resend verification email
curl -X POST https://api.hookbase.app/api/auth/resend-verification \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Login
curl -X POST https://api.hookbase.app/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "your-password"
}'Response:
{
"user": {
"id": "usr_abc123",
"email": "[email protected]",
"displayName": "John Doe"
},
"token": "eyJhbGciOiJIUzI1NiIs...",
"expiresAt": "2024-01-22T10:30:00Z"
}Login with 2FA
If the user has two-factor authentication enabled, the initial login returns a challenge:
{
"requiresTwoFactor": true,
"challengeToken": "2fa-challenge-token"
}Complete the login with the TOTP code:
curl -X POST https://api.hookbase.app/api/auth/login/2fa \
-H "Content-Type: application/json" \
-d '{
"challengeToken": "2fa-challenge-token",
"code": "123456"
}'Forgot Password
# Request password reset
curl -X POST https://api.hookbase.app/api/auth/forgot-password \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'# Reset password with token from email
curl -X POST https://api.hookbase.app/api/auth/reset-password \
-H "Content-Type: application/json" \
-d '{
"token": "reset-token-from-email",
"password": "new-secure-password"
}'OAuth Login
# Redirect user to OAuth provider
# GitHub
GET https://api.hookbase.app/api/auth/oauth/github
# Google
GET https://api.hookbase.app/api/auth/oauth/googleThe OAuth flow redirects the user to the provider, then back to Hookbase with an auth token.
Device Flow (CLI)
The CLI uses the device authorization flow:
# 1. Request device code
curl -X POST https://api.hookbase.app/api/auth/device \
-H "Content-Type: application/json" \
-d '{"clientId": "hookbase-cli"}'
# Response:
# {
# "deviceCode": "abc123",
# "userCode": "ABCD-1234",
# "verificationUrl": "https://www.hookbase.app/auth/device",
# "expiresIn": 900,
# "interval": 5
# }
# 2. User visits verificationUrl and enters userCode
# 3. CLI polls for token
curl -X POST https://api.hookbase.app/api/auth/device/token \
-H "Content-Type: application/json" \
-d '{"deviceCode": "abc123", "clientId": "hookbase-cli"}'Using JWT Tokens
Include the token in the Authorization header:
curl https://api.hookbase.app/api/organizations \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."Token Refresh
Tokens expire after 7 days. Refresh before expiration:
curl -X POST https://api.hookbase.app/api/auth/refresh \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Logout
curl -X POST https://api.hookbase.app/api/auth/logout \
-H "Authorization: Bearer YOUR_JWT_TOKEN"API Keys
API keys are recommended for programmatic access. They don't expire and can be scoped to specific permissions.
Creating an API Key
curl -X POST https://api.hookbase.app/api/api-keys \
-H "Authorization: Bearer whr_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "CI/CD Pipeline",
"scopes": ["sources:read", "events:write"]
}'Response:
{
"id": "key_abc123",
"name": "CI/CD Pipeline",
"key": "whr_live_abc123xyz...",
"scopes": ["sources:read", "events:write"],
"createdAt": "2024-01-15T10:30:00Z"
}Warning
The full API key is only shown once. Store it securely!
Using API Keys
Include the API key in the Authorization header:
curl https://api.hookbase.app/api/sources \
-H "Authorization: Bearer whr_your_api_key"API Key Prefixes
| Prefix | Environment |
|---|---|
whr_live_ | Production |
whr_test_ | Test/sandbox |
Available Scopes
| Scope | Description |
|---|---|
sources:read | Read sources |
sources:write | Create/update/delete sources |
destinations:read | Read destinations |
destinations:write | Create/update/delete destinations |
routes:read | Read routes |
routes:write | Create/update/delete routes |
events:read | Read events |
events:write | Replay events |
deliveries:read | Read deliveries |
analytics:read | Read analytics data |
admin | Full access |
Managing API Keys
List API Keys
curl https://api.hookbase.app/api/api-keys \
-H "Authorization: Bearer whr_your_api_key"Revoke API Key
curl -X DELETE https://api.hookbase.app/api/api-keys/{keyId} \
-H "Authorization: Bearer whr_your_api_key"Security Best Practices
For JWT Tokens
- Store securely: Use secure, HTTP-only cookies in browsers
- Short expiration: Tokens expire after 7 days
- Refresh proactively: Refresh tokens before they expire
- Logout on security events: Logout after password changes
For API Keys
- Use scoped keys: Only grant necessary permissions
- Rotate regularly: Rotate keys periodically
- Use environment variables: Never commit keys to code
- Monitor usage: Review API key activity in the dashboard
- Revoke unused keys: Delete keys that are no longer needed
Environment-Specific Keys
Create separate API keys for each environment:
# Production key
curl -X POST .../api-keys \
-d '{"name": "Production API", "scopes": ["admin"]}'
# Staging key (read-only)
curl -X POST .../api-keys \
-d '{"name": "Staging API", "scopes": ["sources:read", "events:read"]}'Error Responses
401 Unauthorized
Missing or invalid authentication:
{
"error": "Unauthorized",
"message": "Invalid or expired token"
}403 Forbidden
Valid authentication but insufficient permissions:
{
"error": "Forbidden",
"message": "API key does not have required scope: sources:write"
}Example: Complete Auth Flow
// 1. Login to get JWT
const loginResponse = await fetch('https://api.hookbase.app/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: '[email protected]',
password: 'password'
})
});
const { token, user } = await loginResponse.json();
// 2. Get organizations
const orgsResponse = await fetch('https://api.hookbase.app/api/organizations', {
headers: { 'Authorization': `Bearer ${token}` }
});
const { data: orgs } = await orgsResponse.json();
const orgId = orgs[0].id;
// 3. Create an API key for programmatic use
const keyResponse = await fetch(`https://api.hookbase.app/api/organizations/${orgId}/api-keys`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'My App',
scopes: ['sources:read', 'events:read']
})
});
const { key } = await keyResponse.json();
// 4. Use API key for subsequent requests
const sourcesResponse = await fetch('https://api.hookbase.app/api/sources', {
headers: { 'Authorization': `Bearer ${key}` }
});