Authentication
Overview
Affihub supports four authentication methods, each designed for a different use case:
| Method | Used by | Endpoints |
|---|---|---|
| API Key | Provider servers | /api/v1/* |
| Portal Session | Partners (affiliates) | /portal/* |
| Provider Session | Program owners | /provider/* |
| Embed JWT | Embedded widgets | /embed/* |
API Key authentication
Use API keys for server-to-server communication. This is the primary method for managing your affiliate program programmatically.
Getting your API key
Find your API key in the provider dashboard under Settings & Keys, or via the API:
GET /api/v1/programs/meUsing the API key
Include the key in the Authorization header:
curl "https://api.affihub.com/api/v1/partners" \
-H "Authorization: Bearer YOUR_API_KEY"Security
- API keys are hashed (SHA-256) before storage — Affihub never stores the raw key
- Keys have full access to all provider endpoints for your program
- Rotate your key from the dashboard if compromised
Never expose your API key in client-side code, public repositories, or frontend bundles. Use environment variables on your server.
Portal sessions (Partner OTP)
Partners authenticate via email one-time passwords. No passwords are stored.
Login flow
Step 1: Request OTP
curl -X POST "https://api.affihub.com/portal/auth/login" \
-H "Content-Type: application/json" \
-d '{"email": "partner@example.com"}'The partner receives a 6-digit code via email. The code expires in 10 minutes.
Step 2: Verify OTP
curl -X POST "https://api.affihub.com/portal/auth/verify" \
-H "Content-Type: application/json" \
-d '{
"email": "partner@example.com",
"code": "123456"
}'Response:
{
"token": "a1b2c3d4e5f6...",
"partner": {
"id": "par_abc123",
"email": "partner@example.com",
"first_name": "Jane",
"slug": "jane"
}
}Step 3: Use the session token
curl "https://api.affihub.com/portal/data/dashboard" \
-H "Authorization: Bearer a1b2c3d4e5f6..."Session details
- Token: 32-byte hex string
- Stored as SHA-256 hash in the database
- Expires: 30 days
- Rate limit: 5 OTP requests per email per 15 minutes
Check session
curl "https://api.affihub.com/portal/auth/session" \
-H "Authorization: Bearer TOKEN"Logout
curl -X POST "https://api.affihub.com/portal/auth/logout" \
-H "Authorization: Bearer TOKEN"Provider sessions (Program owner OTP)
Program owners use the same OTP flow but through the /provider/auth/* endpoints. The email must match the program's owner_email.
# Request OTP
curl -X POST "https://api.affihub.com/provider/auth/login" \
-H "Content-Type: application/json" \
-d '{"email": "owner@yourcompany.com"}'
# Verify
curl -X POST "https://api.affihub.com/provider/auth/verify" \
-H "Content-Type: application/json" \
-d '{"email": "owner@yourcompany.com", "code": "654321"}'Once authenticated, provider sessions can access all /provider/data/* endpoints, which mirror the /api/v1/* endpoints.
Embed JWT tokens
For embedding partner data in your own application. Tokens are short-lived and scoped to a single partner.
Generate a token
curl -X POST "https://api.affihub.com/api/v1/embed/token" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"partner_id": "par_abc123"}'Response:
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 3600
}Token claims
{
"partner_id": "par_abc123",
"program_id": "prog_xxx",
"scope": "embed",
"iat": 1712880000,
"exp": 1712883600
}Use the token
curl "https://api.affihub.com/embed/data/dashboard" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."Details
- Algorithm: HS256 (HMAC-SHA256)
- Expiry: 1 hour (default)
- Scope:
embed— restricted to/embed/data/*endpoints only - Signed with
EMBED_JWT_SECRETenvironment variable
See Embed Widget for a full integration guide.
Error responses
All authentication errors return a consistent format:
{
"error": "Unauthorized",
"message": "Invalid or expired token"
}| Status | Meaning |
|---|---|
401 |
Missing, invalid, or expired credentials |
403 |
Valid credentials but insufficient permissions |
429 |
Rate limit exceeded (OTP endpoints) |