API Reference
REST API endpoints, authentication methods, rate limits, metering, and usage quotas. All SDK methods map to these endpoints — this reference documents what happens under the hood.
Base URL
https://api.bricqs.ai/api/v1
All API endpoints are relative to this base URL. Self-hosted deployments use your custom domain.
Authentication
The Bricqs API uses two authentication methods depending on the endpoint type.
API Key Authentication
Used by the React SDK, Headless SDK, and server-side integrations. Pass your API key in the X-API-Key header.
# API Key header
curl -X GET https://api.bricqs.ai/api/v1/public/eligibility \
-H "X-API-Key: bq_live_your_key_here" \
-H "Content-Type: application/json"
Key format: bq_live_ (production) or bq_test_ (testing) followed by 32 hex characters. Keys are hashed server-side — the plaintext is shown once on creation.
Session-Based (Anonymous)
Public endpoints for participant-facing operations (activities, points, badges) use session-based identification. No API key required — the session ID is passed as a query parameter or in the request body.
# Session-based request
curl -X POST https://api.bricqs.ai/api/v1/activities/{activityId}/complete-with-actions \
-H "Content-Type: application/json" \
-d '{"session_id": "sess_abc123", "engagement_id": "eng_uuid", ...}'
Rate Limits & API Metering
All API endpoints are rate-limited to ensure fair usage and platform stability. Limits are enforced at three levels: per-IP, per-API key, and per-tenant.
| Scope | Default Limit | Window | Notes |
|---|
| Per IP | 100 requests | 60 seconds | Applies to all endpoints. Prevents single-client abuse. |
| Per API Key | 1,000 requests | 60 seconds | Customizable per key in Settings. Aggregates all IPs using that key. |
| Per Tenant (Public) | 200 requests | 60 seconds | Public-facing endpoints. Plan-tier dependent. |
| Burst (Ingestion) | 100 requests | 1 second | Event ingestion endpoints only. Prevents burst spikes. |
Rate Limit Headers
Every API response includes rate limit information in the headers:
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1707700800
# When rate limited:
HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1707700800
| Header | Description |
|---|
X-RateLimit-Limit | Maximum requests allowed in the current window. |
X-RateLimit-Remaining | Remaining requests in the current window. |
X-RateLimit-Reset | Unix timestamp (seconds) when the window resets. |
Retry-After | Seconds to wait before retrying (only on 429 responses). |
Plan-Based Usage Limits
API quotas scale with your plan. Rate limits, participant caps, and API key allocations increase with each tier.
| Feature | Starter | Growth | Scale | Enterprise |
|---|
| Participants / month | 5,000 | 25,000 | 100,000 | Unlimited |
| API requests / minute | 200 | 1,000 | 5,000 | Custom |
| API keys | 2 | 10 | 50 | Unlimited |
| Event ingestion / day | 10,000 | 100,000 | 1,000,000 | Custom |
| Headless SDK | - | Included | Included | Included |
| Concurrent engagements | 3 | 10 | 50 | Unlimited |
Headless SDK availability: The Headless SDK (custom UI hooks) is available on Growth plans and above. Starter plans can use the Script Tag, iframe, and React SDK (iframe-based) integrations.
Endpoint Reference
All endpoints called by the SDK. Public endpoints use session-based auth; protected endpoints require an API key.
ActivitiesPublic
| Method | Endpoint | Description |
|---|
| POST | /activities/{activityId}/validate | Server-side validation (spin wheel result calculation, quiz scoring). Used by useSpinWheel.spin(). |
| POST | /activities/{activityId}/complete-with-actions | Complete activity and execute all on-completion actions atomically (points, badges, rewards). Returns ActionResults. |
| GET | /activities/{activityId}/eligibility | Check participation limits (max attempts, cooldown period). |
| POST | /activities/facts/emit | Emit a custom fact. Set trigger_challenge_evaluation: true to update challenge progress. |
PointsPublic
| Method | Endpoint | Description |
|---|
| POST | /points/balance | Get current points balance for a session. Used by usePoints(). |
| POST | /points/transactions | Get points transaction history. |
BadgesPublic
| Method | Endpoint | Description |
|---|
| GET | /public/badges/status | Get badge earned/unearned status for a session. Supports filtering by badge_codes. Used by useBadges(). |
ChallengesPublic
| Method | Endpoint | Description |
|---|
| GET | /public/challenges | Get active challenge for an engagement. Returns objectives, milestones, and enrollment status. |
| POST | /public/challenges/{id}/enroll | Enroll a participant in a challenge. Used by useChallenge.enroll(). |
| GET | /public/challenges/{id}/progress | Get challenge progress for a session (objective completion, milestones reached). |
| GET | /public/challenges/{id}/leaderboard | Get challenge leaderboard rankings. |
LeaderboardsPublic
| Method | Endpoint | Description |
|---|
| GET | /public/leaderboards/{code} | Get progression leaderboard by code. Computed on-the-fly. Used by useLeaderboard(). |
RewardsPublic
| Method | Endpoint | Description |
|---|
| GET | /public/rewards/claimed | Get all rewards claimed by a session. Used by useRewards(). |
EligibilityAPI Key Required
| Method | Endpoint | Description |
|---|
| GET | /public/eligibility | Evaluate trigger rules (URL, time, frequency, user attributes). Used by useEligibility(). |
| POST | /public/impressions | Record an impression for frequency cap tracking. |
| GET | /public/engagements/{id}/embed-url | Resolve the runtime embed URL for an engagement. |
Event IngestionAPI Key Required
| Method | Endpoint | Description |
|---|
| POST | /ingest/events | Async event ingestion (<50ms response). Event queued to Redis Stream for background processing. |
| POST | /ingest/events/batch | Batch event ingestion (up to 100 events per request). |
| POST | /ingest/events/sync | Synchronous event processing. Returns event_id and fact_id. Best for testing and debugging. |
Example — Async Event Ingestion
curl -X POST https://api.bricqs.ai/api/v1/ingest/events \
-H "X-API-Key: bq_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"event_name": "purchase_completed",
"participant_id": "user_123",
"properties": {
"amount": 49.99,
"currency": "USD",
"product_id": "prod_abc"
},
"timestamp": "2026-02-14T10:30:00Z"
}'
# Response (< 50ms)
{
"accepted": true,
"message_id": "1707900600000-0"
}
Example — Batch Ingestion
curl -X POST https://api.bricqs.ai/api/v1/ingest/events/batch \
-H "X-API-Key: bq_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"events": [
{"event_name": "page_view", "participant_id": "user_123", "properties": {"page": "/products"}},
{"event_name": "add_to_cart", "participant_id": "user_123", "properties": {"product_id": "prod_abc"}},
{"event_name": "purchase_completed", "participant_id": "user_123", "properties": {"amount": 49.99}}
]
}'
EngagementsPublic
| Method | Endpoint | Description |
|---|
| GET | /sites/{tenantSlug}/{siteSlug} | Get published engagement by slug. Returns full site definition including components and canvas. |
API Key Management Endpoints
Manage API keys programmatically. These endpoints require JWT authentication (Builder admin login).
| Method | Endpoint | Description |
|---|
| POST | /events/api-keys | Create a new API key. Returns the plaintext key (shown once). |
| GET | /events/api-keys | List all API keys for the tenant (key prefixes only, not full keys). |
| PATCH | /events/api-keys/{id} | Update key name, scopes, or rate limit. |
| DELETE | /events/api-keys/{id} | Revoke (soft-delete) an API key. Takes effect immediately. |
Error Responses
All API errors follow a consistent format:
// Error response format
{
"detail": "Human-readable error message"
}
// Common HTTP status codes
400 Bad Request — Invalid parameters or request body
401 Unauthorized — Missing or invalid API key
403 Forbidden — API key doesn't have required scope
404 Not Found — Resource doesn't exist
409 Conflict — Duplicate action (e.g., already enrolled)
429 Too Many Requests — Rate limit exceeded (check Retry-After header)
500 Internal Error — Server error (please report)
SDK Error Handling
The SDK handles common error scenarios automatically. For custom error handling:
// React SDK
<BricqsEngagement
id="YOUR_UUID"
onError={(error) => {
if (error.status === 429) {
showToast('Please wait a moment and try again');
} else if (error.status === 404) {
showToast('This engagement is no longer available');
} else {
console.error('Bricqs error:', error);
}
}}
/>
// Headless SDK
const quiz = useQuiz({ engagementId: '...', activityId: '...', config });
// Errors are caught during submit()
try {
await quiz.submit();
} catch (error) {
// Handle submission errors
console.error('Submit failed:', error);
}