Retrieve a list of all QR code scans (impressions) from posters in your programs. This endpoint helps you track engagement, monitor scan activity, and analyze which posters are performing best.
Overview
The List Impressions endpoint returns a paginated list of all QR code scans. Use this endpoint to:
- Track all QR code scans across your programs
- Monitor which posters generate the most engagement
- Filter impressions by program or poster
- Build analytics dashboards for scan activity
- Analyze conversion funnel from scan to signup
Authentication
This endpoint requires authentication using a Bearer token in the Authorization header:
Authorization: Bearer sk_your_secret_key_here
Query Parameters
Filter results to only include impressions from a specific program. Useful when analyzing scan activity for individual programs.Example: programId=prog_123abc
Filter results to only include impressions from a specific poster. Use this to see all scans for a particular poster placement.Example: posterId=poster_123abc
Maximum number of results to return per page. Default is 50, maximum is typically 100.Example: limit=25
Number of results to skip before starting to return results. Use for pagination.Example: offset=50 skips the first 50 results
Request Example
# Get all impressions
curl -X GET "http://localhost:3000/api/v1/impressions" \
-H "Authorization: Bearer sk_your_secret_key_here"
# Get impressions from a specific program
curl -X GET "http://localhost:3000/api/v1/impressions?programId=prog_123abc&limit=100" \
-H "Authorization: Bearer sk_your_secret_key_here"
# Get impressions from a specific poster
curl -X GET "http://localhost:3000/api/v1/impressions?posterId=poster_123abc" \
-H "Authorization: Bearer sk_your_secret_key_here"
Response
The API returns a JSON object containing an array of impression objects:
Array of impression objects, each containing information about a QR code scan.
Each impression object contains:
Unique identifier for the impression. This ID is used when creating referrals.
ID of the poster whose QR code was scanned.
ID of the program this impression belongs to.
ID of the student ambassador who placed the poster.
ISO 8601 timestamp of when the QR code was scanned.
User agent string of the device that scanned the QR code.
IP address of the device that scanned the QR code (if available).
Additional metadata about the scan, such as device type, location, or custom fields.
Response Example
{
"impressions": [
{
"id": "imp_123abc",
"poster_id": "poster_123abc",
"program_id": "prog_123abc",
"student_id": "user_123abc",
"scanned_at": "2024-01-15T10:30:00Z",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)",
"ip_address": "192.168.1.1",
"metadata": {
"device_type": "mobile",
"location": "campus_center"
}
},
{
"id": "imp_456def",
"poster_id": "poster_123abc",
"program_id": "prog_123abc",
"student_id": "user_123abc",
"scanned_at": "2024-01-15T11:15:00Z",
"user_agent": "Mozilla/5.0 (Android 13; Mobile)",
"ip_address": "192.168.1.2",
"metadata": {
"device_type": "mobile",
"location": "library"
}
}
]
}
Use Cases
Building an Impressions Dashboard
Fetch all impressions and display them in a dashboard:
async function fetchImpressions(filters = {}) {
const params = new URLSearchParams();
if (filters.programId) params.append('programId', filters.programId);
if (filters.posterId) params.append('posterId', filters.posterId);
if (filters.limit) params.append('limit', filters.limit);
if (filters.offset) params.append('offset', filters.offset);
const response = await fetch(
`http://localhost:3000/api/v1/impressions?${params.toString()}`,
{
headers: {
'Authorization': `Bearer ${API_KEY}`
}
}
);
return await response.json();
}
Analyzing Poster Performance
See which posters generate the most scans:
async function getPosterScanStats(programId) {
const impressions = await fetchImpressions({ programId, limit: 1000 });
// Count scans by poster
const stats = {};
impressions.impressions.forEach(impression => {
if (!stats[impression.poster_id]) {
stats[impression.poster_id] = 0;
}
stats[impression.poster_id]++;
});
return stats;
}
Tracking Conversion Funnel
Link impressions to referrals to track conversion:
async function getConversionFunnel(posterId) {
const impressions = await fetchImpressions({ posterId, limit: 1000 });
// For each impression, check if there's a corresponding referral
const funnel = {
scans: impressions.impressions.length,
signups: 0,
conversions: 0
};
for (const impression of impressions.impressions) {
// Check if referral exists for this impression
const referrals = await fetchReferrals({
// You would need to filter by impression_id if supported
});
// Count signups and conversions
// This is a simplified example
}
return funnel;
}
Exporting Impression Data
Fetch all impressions for export:
async function exportAllImpressions(programId) {
let allImpressions = [];
let offset = 0;
const limit = 100;
let hasMore = true;
while (hasMore) {
const response = await fetch(
`http://localhost:3000/api/v1/impressions?programId=${programId}&limit=${limit}&offset=${offset}`,
{
headers: {
'Authorization': `Bearer ${API_KEY}`
}
}
);
const data = await response.json();
allImpressions = [...allImpressions, ...data.impressions];
hasMore = data.impressions.length === limit;
offset += limit;
}
return allImpressions;
}
Best Practices
- Use filters effectively - Combine programId and posterId to narrow results
- Implement pagination - Always use
limit and offset for large datasets
- Link to referrals - Use impression IDs when creating referrals to maintain the funnel
- Track device types - Use metadata to store device information for analytics
- Monitor scan rates - Compare impressions to poster placements to measure engagement
Error Responses
Unauthorized - Invalid or missing API key{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}
Rate Limits
This endpoint is subject to rate limiting. Check response headers for rate limit information.Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Maximum number of results to return
Number of results to skip
The response is of type object.