docs / authentication
Generate access token
Before calling any secured endpoint, your server must exchange its credentials for a short-lived JWT. This page explains every aspect of the authentication handshake — headers, response shape, token lifecycle, caching strategy, and security requirements.
GETsandboxhttps://sandbox.synergicpay.com/auth/token
Quick reference
Method
GET
Authentication
Header-based (no body)
Token lifetime
3600 seconds (1 hour)
Token type
JWT · Bearer scheme
Requires body
No
Rate limiting
Yes — cache the token
How it works
Synergic Payments uses a two-credential model. You hold a public API key (your identity) and a private secret key (your proof of ownership).
1
Send credentials as request headers
GET to /auth/token with x-api-key and x-secret-key set in HTTP headers. No request body is required.2
Synergic Payments validates and signs a JWT
The API looks up your API key, verifies the secret key matches via a timing-safe comparison, and if successful, signs a JWT using its private key.
3
Cache the token server-side
Store the
access_token in memory or Redis. Record Date.now() at receipt to compute expiry.4
Attach the token to all subsequent requests
Every secured endpoint requires the token in the
Authorization header using the Bearer scheme.5
Proactively refresh before expiry
Build a 60-second refresh buffer. Before each outgoing request, check
Date.now() > (expiresAt - 60_000).Token lifecycle
→
Request
GET /auth/token
Headers only
→
Issued at
t = 0s
Cache token now
→
Refresh window
t = 3540s
60s before expiry
Expires
t = 3600s
Token invalid after
Refresh the token in the background during the window between t = 3540s and t = 3600s.
Request headers
| Header name | Required | Type | Description & notes |
|---|---|---|---|
x-api-key | Required | string | Your account's public identifier. Never appear in client-side code. |
x-secret-key | Required | string | Your private credential. Store only in environment variables or a secrets manager. |
⚠
Header names are case-insensitive in HTTP/1.1Both
x-api-key and X-API-Key are valid. However, send them exactly as documented.Example requests
HTTP raw
GET /auth/token HTTP/1.1 Host: api.synergicpay.com x-api-key: pk_live_a1b2c3d4e5f6g7h8 x-secret-key: sk_live_z9y8x7w6v5u4t3s2
cURL
curl -X GET \ 'https://api.synergicpay.com/auth/token' \ -H 'x-api-key: pk_live_a1b2c3d4e5f6g7h8' \ -H 'x-secret-key: sk_live_z9y8x7w6v5u4t3s2'
JavaScript · fetch
const getAccessToken = async () => { const response = await fetch( 'https://api.synergicpay.com/auth/token', { method: 'GET', headers: { 'x-api-key': process.env.SYNERGICPAY_API_KEY, 'x-secret-key': process.env.SYNERGICPAY_SECRET_KEY, }, } ); if (!response.ok) throw new Error(`Auth failed: ${response.status}`); const { data } = await response.json(); return { token: data.access_token, expiresAt: Date.now() + data.expires_in * 1000, }; };
Success response · 200 OK
JSON
{ "status": "success", "data": { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "expires_in": 3600 } }
| Field | Type | Description |
|---|---|---|
status | string | Always "success" for 2xx responses. |
data.access_token | string | A signed JWT. Treat as opaque. |
data.expires_in | integer | Seconds until invalid. Currently 3600. |
Using the token on subsequent requests
All secured endpoints require the token in the Authorization header using the HTTP Bearer scheme:
HTTP header
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
✕
Common mistake: missing "Bearer " prefixSending just the token without the
Bearer prefix will result in a 401 Unauthorized.Error responses
| Status | Meaning | Cause & resolution |
|---|---|---|
| 200 | OK | Authentication succeeded. |
| 400 | Bad Request | A required header is missing. |
| 401 | Unauthorized | Credentials present but invalid. Do not retry automatically. |
| 403 | Forbidden | Account suspended or lacks permission. |
| 429 | Too Many Requests | Cache the token. Implement exponential backoff. |
| 500 | Server Error | Transient infrastructure error. Safe to retry. |
Security requirements
Do
- ✓Store credentials exclusively in environment variables or a secrets manager
- ✓Call this endpoint only from your backend server
- ✓Cache the token for its full
expires_induration - ✓Build a proactive refresh buffer of at least 60 seconds before expiry
- ✓Rotate credentials immediately if the secret key has been exposed
- ✓Use HTTPS exclusively — never send credentials over plain HTTP
Do not
- ✕Embed
x-secret-keyin client-side bundles or public repos - ✕Re-authenticate on every API request — risks rate limiting
- ✕Log the secret key or the raw token at any severity level
- ✕Share the token across environments
- ✕Decode the JWT to extract claims — the payload may change
- ✕Retry on a
401automatically — it will always fail
Retry strategy
| Status | Retry? | Strategy |
|---|---|---|
| 400 | No | Fix the missing header before retrying. |
| 401 / 403 | No | Alert immediately. Retrying will always fail. |
| 429 | Yes — with backoff | Honour the Retry-After header, then retry. |
| 500 / 502 / 503 | Yes — with backoff | Exponential backoff: 1s, 2s, 4s, 8s… Cap at 60s. |
