The Spike API uses JWT (JSON Web Token) authentication. Your backend server requests tokens from the Spike token minting API, which are then used to authenticate API requests from your client applications.
How it works
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Your Client │ │ Your Backend │ │ Spike API │
│ (App/Web) │ │ Server │ │ │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
│ 1. Request token │ │
│ ─────────────────────► │ │
│ │ │
│ │ 2. POST /tenant/api/tokens/mint
│ │ (with API Key) │
│ │ ──────────────────────►│
│ │ │
│ │ 3. Signed JWT │
│ │ ◄──────────────────────│
│ │ │
│ 4. Return JWT │ │
│ ◄───────────────────── │ │
│ │ │
│ 5. API request with Bearer token │
│ ───────────────────────────────────────────────►│
│ │ │
│ 6. Response │ │
│ ◄───────────────────────────────────────────────│
Your client requests a token from your backend
Your backend calls the Spike token minting API with your API key
Spike generates and signs a JWT for the user
Your backend returns the JWT to the client
The client includes the JWT in API requests
Spike validates the token and processes the request
API Key
Your API key is available in the Spike Console . This key authenticates your backend to the token minting API and identifies your tenant.
Your API key is sensitive. Keep it secure and never include it in client-side code, public repositories, or logs. Only use it on your backend server.
Minting Tokens
POST /tenant/api/tokens/mint
Request a JWT for an end user by calling the token minting endpoint from your backend.
Required Headers:
Authorization: Bearer <your-api-key> - Your Spike API key
Content-Type: application/json
Request Body:
Field Type Required Description user_idstring Yes Unique identifier for the end user in your system namestring No User's display name emailstring No User's email address scopesstring[] No Permission scopes for the token exp_secondsnumber No Token lifetime in seconds (default: 3600, max: 86400)
Response:
{
"token" : "eyJhbGciOiJSUzI1NiIs..." ,
"expires_at" : "2024-01-15T12:00:00.000Z"
}
Token Structure
The minted JWT contains the following claims:
Claim Type Description issstring Token issuer (Spike tenant service) substring Subject: {tenant_id}:{user_id} tenant_idstring Your tenant identifier (set automatically from API key) user_idstring The user ID you provided namestring User's display name (if provided) emailstring User's email (if provided) scopesstring[] Permission scopes (if provided) iatnumber Issued at timestamp expnumber Expiration timestamp
Example Token Payload
{
"iss" : "https://tenant-api.internal.spikelabs.com" ,
"sub" : "tenant_abc123:user_12345" ,
"tenant_id" : "tenant_abc123" ,
"user_id" : "user_12345" ,
"name" : "Jane Doe" ,
"email" : "[email protected] " ,
"scopes" : [ "read" , "write" ],
"iat" : 1704150000 ,
"exp" : 1704153600
}
Backend Integration
Node.js
const SPIKE_API_KEY = process.env. SPIKE_API_KEY ;
const SPIKE_API_URL = process.env. SPIKE_API_URL || 'https://api.spikelabs.com' ;
async function getSpikeToken ( userId , userData = {}) {
const response = await fetch ( `${ SPIKE_API_URL }/tenant/api/tokens/mint` , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'Authorization' : `Bearer ${ SPIKE_API_KEY }` ,
},
body: JSON . stringify ({
user_id: userId,
name: userData.name,
email: userData.email,
scopes: userData.scopes,
exp_seconds: 3600 , // 1 hour
}),
});
if ( ! response.ok) {
const error = await response. json ();
throw new Error (error.error || 'Failed to mint token' );
}
return response. json ();
}
// Express endpoint example
app. get ( '/api/spike-token' , authenticateUser, async ( req , res ) => {
try {
const { token , expires_at } = await getSpikeToken (req.user.id, {
name: req.user.name,
email: req.user.email,
});
res. json ({ token, expires_at });
} catch (error) {
res. status ( 500 ). json ({ error: error.message });
}
});
Python
import os
import requests
SPIKE_API_KEY = os.environ[ 'SPIKE_API_KEY' ]
SPIKE_API_URL = os.environ.get( 'SPIKE_API_URL' , 'https://api.spikelabs.com' )
def get_spike_token (user_id, user_data = None ):
user_data = user_data or {}
response = requests.post(
f ' {SPIKE_API_URL} /tenant/api/tokens/mint' ,
headers = {
'Content-Type' : 'application/json' ,
'Authorization' : f 'Bearer {SPIKE_API_KEY} ' ,
},
json = {
'user_id' : user_id,
'name' : user_data.get( 'name' ),
'email' : user_data.get( 'email' ),
'scopes' : user_data.get( 'scopes' ),
'exp_seconds' : 3600 , # 1 hour
},
)
response.raise_for_status()
return response.json()
# Flask endpoint example
@app.route ( '/api/spike-token' )
@login_required
def get_token ():
try :
result = get_spike_token(
current_user.id,
{ 'name' : current_user.name, 'email' : current_user.email}
)
return jsonify(result)
except requests.HTTPError as e:
return jsonify({ 'error' : str (e)}), 500
Making API Requests
Include the JWT in the Authorization header as a Bearer token:
curl https://api.spikelabs.com/platform/api/workspaces \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{"tier": "md", "ttlSeconds": 3600}'
SDK Authentication
The Spike SDK supports three authentication methods:
1. Direct Token
Pass a token directly when initializing the SDK:
import { SpikeClient } from '@spike/sdk' ;
const client = new SpikeClient ({
token: 'eyJhbGciOiJSUzI1NiIs...' ,
});
2. Token Provider Function
Pass an async function that returns a fresh token. The SDK calls this function when tokens expire:
import { SpikeClient } from '@spike/sdk' ;
const client = new SpikeClient ({
tokenProvider : async () => {
const response = await fetch ( '/api/spike-token' );
const data = await response. json ();
return data.token;
},
});
3. Token Endpoint Path
Pass a URL path that returns { token: string }. The SDK handles fetching and refreshing:
import { SpikeClient } from '@spike/sdk' ;
const client = new SpikeClient ({
tokenEndpoint: '/api/spike-token' ,
});
Your endpoint should return:
{
"token" : "eyJhbGciOiJSUzI1NiIs..."
}
Token Expiration
We recommend short-lived tokens (1 hour or less) for security. The SDK automatically handles token refresh when using tokenProvider or tokenEndpoint.
If a token expires mid-request, the API returns:
{
"error" : "token_expired" ,
"message" : "Token has expired"
}
Error Responses
Status Error Description 401 unauthorizedMissing or invalid Authorization header 401 invalid_tokenToken is malformed or has invalid claims 401 invalid_signatureToken signature verification failed 401 invalid_issuerToken issuer is not trusted 401 token_expiredToken has expired
Example error response:
{
"error" : "invalid_token" ,
"message" : "Token must contain tenant_id claim"
}
Security Best Practices
Never expose your API key in client-side code or public repositories
Use short token lifetimes (1 hour or less) to limit exposure if compromised
Validate user identity on your backend before requesting tokens
Use HTTPS for all API requests and token endpoints
Monitor for anomalies in the Spike Console analytics
Last modified on March 2, 2026