Overview
Complete overview for the Stacked REST API and real-time events
The Stacked API provides programmatic access to the offers platform, allowing you to fetch personalized campaigns, claim rewards, and receive real-time updates for your players.
Base URL
https://api.sandbox.pixels.xyz/v1TEST
All API endpoints are prefixed with /v1. For example, to fetch player campaigns:
https://api.sandbox.pixels.xyz/v1/client/player/campaigns
Authentication
Stacked supports two authentication methods designed for different use cases:
- JWT Authentication - For client-side requests from end-user devices
- API Key Authentication - For server-side requests from your game servers
Learn more about authentication →
Quick Start
# Fetch campaigns using JWT
curl -X POST https://api.pixels.xyz/v1/client/player/campaigns \
-H "Content-Type: application/json" \
-H "x-game-jwt: YOUR_JWT_TOKEN" \
-d '{"viewingCampaigns": true}'// Example JavaScript implementation
const response = await fetch('https://api.pixels.xyz/v1/client/player/campaigns', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-game-jwt': jwt // JWT generated by your server
},
body: JSON.stringify({
viewingCampaigns: true
})
});
const { offers, snapshot } = await response.json();# Fetch campaigns using API Key
curl -X POST https://api.pixels.xyz/v1/player/campaigns/refresh \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-client-id: YOUR_CLIENT_ID" \
-d '{"playerId": "player-123", "viewingCampaigns": false}'// Example JavaScript implementation
const response = await fetch('https://api.pixels.xyz/v1/player/campaigns/refresh', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'your-api-key',
'x-client-id': 'your-client-id'
},
body: JSON.stringify({
playerId: 'player-123',
viewingCampaigns: false
})
});
const { offers, token } = await response.json();API Sections
Authentication
JWT and API Key authentication methods
Campaigns
Fetch personalized offers for players
Rewards
Claim rewards for completed offers
Server-Sent Events
Real-time offer updates via SSE
Error Handling
Error codes and best practices
Rate Limits
Fair Usage
The Stacked API does not enforce strict rate limits, but we expect fair usage. If you need to make high-volume requests, please contact us to discuss your use case.
Recommended guidelines:
- Campaign fetching: Once per player session or when offers are viewed
- SSE connections: One connection per active client
- Reward claiming: As needed when players complete offers
Best Practices
Caching
Cache campaign responses on the client to reduce API calls:
// Cache for 5 minutes
const CACHE_TTL = 5 * 60 * 1000;
let cachedOffers = null;
let cacheTime = 0;
async function getCampaigns() {
if (cachedOffers && Date.now() - cacheTime < CACHE_TTL) {
return cachedOffers;
}
const response = await fetchCampaigns();
cachedOffers = response;
cacheTime = Date.now();
return response;
}Error Handling
Always handle authentication errors and retry with a fresh JWT:
async function fetchWithRetry(url, options) {
try {
const response = await fetch(url, options);
const data = await response.json();
if (response.status === 400 && data.message === 'jwt-expired') {
// Refresh JWT and retry
const newJWT = await getNewJWT();
options.headers['x-game-jwt'] = newJWT;
return fetch(url, options);
}
return response;
} catch (error) {
console.error('API request failed:', error);
throw error;
}
}Real-time Updates
Use SSE for real-time offer updates instead of polling:
const eventSource = new EventSource(
'https://api.pixels.xyz/v1/sse/connect',
{
headers: { 'x-game-jwt': jwt }
}
);
eventSource.addEventListener('offer_surfaced', (event) => {
const offer = JSON.parse(event.data);
displayNewOffer(offer);
});
Stacked