API keys and auth
API Keys and Authentication
All requests to the Get Plus gateway require a Bearer JWT in the Authorization header. This page explains how to obtain, refresh, and revoke tokens.
Authentication flow
┌──────────────┐ ┌───────────────────┐ ┌───────────────────┐
│ Your system │──(1)──▸│ POST /auth/v1/ │──(2)──▸│ Use JWT on all │
│ │ │ token │ │ subsequent calls │
└──────────────┘ └───────────────────┘ └───────────────────┘
X-API-Key JWT Bearer <jwt>
X-Shop-Domain (60 min TTL)
- Exchange your API key + shop domain for a JWT.
- Use the JWT as
Authorization: Bearer <token>on all data endpoints. - When the token expires, request a new one (step 1 again).
API key lifecycle
| Action | How |
|---|---|
| Generate | Dashboard → Tracking → Integration → API Key card → Generate. Or POST /api-keys/generate from internal services. |
| Rotate | Same card → Rotate. The old key is invalidated immediately; any in-flight JWTs issued from it remain valid until their own expires_at. |
| Revoke | Same card → Revoke. The key and all JWTs issued from it are invalidated. |
| List | GET /api-keys/list/:storeId — returns the active key (masked) or null. |
Key format: pplus_<64 hex characters>.
Token details
| Field | Value |
|---|---|
| Algorithm | HS256 |
| Lifetime | 3600 seconds (60 minutes) |
| Issuer | protectplus-public-apis |
| Claims | merchantId, storeId, jti (unique ID), iat, exp |
Refresh strategy
The gateway does NOT issue refresh tokens. When your JWT is close to expiry:
- Request a new JWT from the same API key (same
POST /auth/v1/tokencall). - Swap the old token for the new one in your HTTP client.
- The old token remains valid until its
exp— no disruption to in-flight requests.
Recommendation: refresh when expires_at minus current time is under 5 minutes.
Revocation
Revoke a specific JWT (e.g. a leaked token) without rotating the API key:
curl -X POST $BASE_URL/auth/v1/token/revoke \
-H "Content-Type: application/json" \
-d '{ "token": "<jwt-to-revoke>", "reason": "compromised" }'Revoked JWTs are checked against a persistent blocklist on every request — the rejection is instant, not TTL-dependent.
Introspection and verification
| Endpoint | Use |
|---|---|
POST /auth/v1/token/verify | Returns { valid: true/false, jti, merchantId, storeId } — lightweight "is this JWT live?" check. |
GET /auth/v1/token/introspect | Returns decoded claims without verifying expiry — debug tool. |
Rate limits
| Scope | Limit |
|---|---|
Token issuance (POST /auth/v1/token) | 20 per 15 minutes per API key |
| Data endpoints (all other routes) | 100 per minute per store |
429 responses include a Retry-After header (seconds).
Security notes
- Store your API key in a secrets manager (Vault, AWS SSM, GCP Secret Manager) — not in source code.
- The gateway strips
X-Store-Id,X-Merchant-Id, and other sensitive headers from inbound requests. Do not attempt to spoof tenant context — it will be overwritten by the JWT-derived values. - All traffic must be TLS 1.2+. Plain HTTP is not supported.
Updated about 1 month ago
Did this page help you?