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)
  1. Exchange your API key + shop domain for a JWT.
  2. Use the JWT as Authorization: Bearer <token> on all data endpoints.
  3. When the token expires, request a new one (step 1 again).

API key lifecycle

ActionHow
GenerateDashboard → Tracking → Integration → API Key card → Generate. Or POST /api-keys/generate from internal services.
RotateSame card → Rotate. The old key is invalidated immediately; any in-flight JWTs issued from it remain valid until their own expires_at.
RevokeSame card → Revoke. The key and all JWTs issued from it are invalidated.
ListGET /api-keys/list/:storeId — returns the active key (masked) or null.

Key format: pplus_<64 hex characters>.


Token details

FieldValue
AlgorithmHS256
Lifetime3600 seconds (60 minutes)
Issuerprotectplus-public-apis
ClaimsmerchantId, storeId, jti (unique ID), iat, exp

Refresh strategy

The gateway does NOT issue refresh tokens. When your JWT is close to expiry:

  1. Request a new JWT from the same API key (same POST /auth/v1/token call).
  2. Swap the old token for the new one in your HTTP client.
  3. 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

EndpointUse
POST /auth/v1/token/verifyReturns { valid: true/false, jti, merchantId, storeId } — lightweight "is this JWT live?" check.
GET /auth/v1/token/introspectReturns decoded claims without verifying expiry — debug tool.

Rate limits

ScopeLimit
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.

Did this page help you?