API Reference
The Basestack Feature Flags REST API provides a simple, HTTP-based interface for retrieving feature flags. This API is used by all Basestack SDKs under the hood and can also be used directly in any application that can make HTTP requests.
The API uses standard HTTP methods and returns JSON responses, making it easy to integrate with any programming language or framework. Most requests authenticate with your project and environment keys; uploading code references also requires a project API token (x-api-key).
Base URL
All API requests should be made to your Basestack instance:
https://flags-api.basestack.co/v1If you're using a self-hosted instance, replace the base URL with your own domain. The API version (/v1) is required for all requests.
Authentication
Most API requests require two custom headers for authentication:
| Header | Description | Required |
|---|---|---|
x-project-key | Your project identifier | Yes |
x-environment-key | Your environment identifier (e.g., development, staging, production) | Yes |
You can find these values in your Basestack Feature Flags Dashboard under your project settings.
POST /v1/flags/code-refs additionally requires x-api-key: a project API token you create in project settings. Without a valid API key, the request returns 401 Unauthorized. See Submit code references.
Getting Started
Get Your API Credentials
Before making API requests, you'll need your project and environment keys:
- Log in to your Basestack Feature Flags Dashboard
- Navigate to your project settings
- Copy your Project Key and Environment Key
These keys identify which project and environment you're querying flags from.
Make Your First Request
Test the API by fetching a single flag. Replace the placeholders with your actual values:
curl "https://flags-api.basestack.co/v1/flags/header" \
-H "x-project-key: your-project-key" \
-H "x-environment-key: your-environment-key"If successful, you'll receive a JSON response with the flag details.
Endpoints
Get a Flag by Slug
Retrieve a specific feature flag by its slug (name). This endpoint returns a single flag object with all its properties.
Endpoint: GET /flags/:slug
Path Parameters:
| Parameter | Type | Description | Required |
|---|---|---|---|
slug | string | The unique identifier (slug) of the flag | Yes |
Headers:
| Header | Type | Description | Required |
|---|---|---|---|
x-project-key | string | Your project identifier | Yes |
x-environment-key | string | Your environment identifier | Yes |
Example Request:
curl "https://flags-api.basestack.co/v1/flags/header" \
-H "x-project-key: your-project-key" \
-H "x-environment-key: your-environment-key"const response = await fetch('https://flags-api.basestack.co/v1/flags/header', {
headers: {
'x-project-key': 'your-project-key',
'x-environment-key': 'your-environment-key',
},
});
const flag = await response.json();
console.log(flag);import requests
headers = {
'x-project-key': 'your-project-key',
'x-environment-key': 'your-environment-key',
}
response = requests.get(
'https://flags-api.basestack.co/v1/flags/header',
headers=headers
)
flag = response.json()
print(flag)<?php
$headers = [
'x-project-key: your-project-key',
'x-environment-key: your-environment-key',
];
$ch = curl_init('https://flags-api.basestack.co/v1/flags/header');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$flag = json_decode($response, true);
curl_close($ch);Response Codes:
| Status Code | Description |
|---|---|
200 | Success - Flag found and returned |
404 | Flag not found |
400 | Bad request - Server error or invalid request |
Success Response (200):
The flag object is returned directly (not wrapped in an object). Note that createdAt and updatedAt are not included in this endpoint:
{
"slug": "header",
"enabled": true,
"payload": {
"variant": "dark",
"showLogo": true
},
"expiredAt": null,
"description": "Controls the header visibility and styling"
}Response Headers:
The response includes cache headers for optimal performance:
Cache-Control: public, s-maxage=60, max-age=30, stale-while-revalidate=60, stale-if-error=300Error Response (404):
When a flag with the specified slug doesn't exist:
{
"enabled": false,
"error": true,
"message": "Flag with slug header does not exist"
}Error Response (400):
When a server error occurs or the request is invalid:
{
"error": true,
"message": "Something went wrong, please try again later."
}Even when a flag doesn't exist, the API returns a response with enabled: false and error: true. This allows your application to handle missing flags gracefully without throwing exceptions.
Get All Flags
Retrieve all feature flags for a specific project and environment. This endpoint returns an array of all flags, useful for preloading or displaying a list of available flags.
Endpoint: GET /flags
Headers:
| Header | Type | Description | Required |
|---|---|---|---|
x-project-key | string | Your project identifier | Yes |
x-environment-key | string | Your environment identifier | Yes |
Example Request:
curl "https://flags-api.basestack.co/v1/flags" \
-H "x-project-key: your-project-key" \
-H "x-environment-key: your-environment-key"const response = await fetch('https://flags-api.basestack.co/v1/flags', {
headers: {
'x-project-key': 'your-project-key',
'x-environment-key': 'your-environment-key',
},
});
const { flags } = await response.json();
console.log(`Found ${flags.length} flags`);
flags.forEach(flag => {
console.log(`${flag.slug}: ${flag.enabled}`);
});import requests
headers = {
'x-project-key': 'your-project-key',
'x-environment-key': 'your-environment-key',
}
response = requests.get(
'https://flags-api.basestack.co/v1/flags',
headers=headers
)
data = response.json()
flags = data['flags']
print(f"Found {len(flags)} flags")
for flag in flags:
print(f"{flag['slug']}: {flag['enabled']}")<?php
$headers = [
'x-project-key: your-project-key',
'x-environment-key: your-environment-key',
];
$ch = curl_init('https://flags-api.basestack.co/v1/flags');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$data = json_decode($response, true);
$flags = $data['flags'];
echo "Found " . count($flags) . " flags\n";
foreach ($flags as $flag) {
echo $flag['slug'] . ": " . ($flag['enabled'] ? 'enabled' : 'disabled') . "\n";
}
curl_close($ch);Response Codes:
| Status Code | Description |
|---|---|
200 | Success - Flags retrieved successfully (may be empty array) |
400 | Bad request - Server error or invalid request |
Success Response (200):
Flags are returned in an array, ordered by creation date (newest first). Each flag includes all fields including createdAt and updatedAt:
{
"flags": [
{
"slug": "footer",
"enabled": true,
"payload": {
"theme": "light"
},
"expiredAt": null,
"description": "Controls footer visibility",
"createdAt": "2023-07-20T14:08:27.284Z",
"updatedAt": "2023-07-20T14:08:27.284Z"
},
{
"slug": "header",
"enabled": true,
"payload": {
"variant": "dark",
"showLogo": true
},
"expiredAt": null,
"description": "Controls the header visibility and styling",
"createdAt": "2023-07-20T14:08:16.433Z",
"updatedAt": "2023-07-20T14:08:16.433Z"
}
]
}Response Headers:
The response includes cache headers for optimal performance:
Cache-Control: public, s-maxage=60, max-age=30, stale-while-revalidate=60, stale-if-error=300Empty Response (200):
If no flags exist for the environment, an empty array is returned (still a 200 status):
{
"flags": []
}Error Response (400):
When a server error occurs or the request is invalid:
{
"error": true,
"message": "Something went wrong, please try again later."
}Get Preview Flags
Retrieve preview flags for a project and environment. Preview flags include additional fields used to render preview content and are returned with previewContent converted to HTML.
Endpoint: GET /flags/preview
Headers:
| Header | Type | Description | Required |
|---|---|---|---|
x-project-key | string | Your project identifier | Yes |
x-environment-key | string | Your environment identifier | Yes |
Example Request:
curl "https://flags-api.basestack.co/v1/flags/preview" \
-H "x-project-key: your-project-key" \
-H "x-environment-key: your-environment-key"const response = await fetch('https://flags-api.basestack.co/v1/flags/preview', {
headers: {
'x-project-key': 'your-project-key',
'x-environment-key': 'your-environment-key',
},
});
const { flags } = await response.json();
console.log(`Found ${flags.length} preview flags`);import requests
headers = {
'x-project-key': 'your-project-key',
'x-environment-key': 'your-environment-key',
}
response = requests.get(
'https://flags-api.basestack.co/v1/flags/preview',
headers=headers
)
data = response.json()
flags = data['flags']
print(f"Found {len(flags)} preview flags")<?php
$headers = [
'x-project-key: your-project-key',
'x-environment-key: your-environment-key',
];
$ch = curl_init('https://flags-api.basestack.co/v1/flags/preview');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$data = json_decode($response, true);
$flags = $data['flags'];
echo "Found " . count($flags) . " preview flags\n";
curl_close($ch);Response Codes:
| Status Code | Description |
|---|---|
200 | Success - Preview flags retrieved successfully (may be empty array) |
500 | Server error |
Success Response (200):
{
"flags": [
{
"slug": "landing-preview",
"enabled": true,
"isPreview": true,
"previewName": "Landing Hero Copy",
"previewContent": "<p>Try our new hero copy variation.</p>",
"expiredAt": null,
"createdAt": "2023-07-20T14:08:27.284Z"
}
]
}Response Headers:
The response includes cache headers for optimal performance:
Cache-Control: public, s-maxage=60, max-age=30, stale-while-revalidate=60, stale-if-error=300Empty Response (200):
{
"flags": []
}Error Response (500):
{
"error": true,
"message": "Something went wrong, please try again later."
}Submit Preview Feedback
Submit feedback for a preview flag. This endpoint stores qualitative and quantitative feedback for preview experiments.
Endpoint: POST /flags/preview/feedback
Headers:
| Header | Type | Description | Required |
|---|---|---|---|
x-project-key | string | Your project identifier | Yes |
x-environment-key | string | Your environment identifier | Yes |
Request Body:
| Field | Type | Description | Required |
|---|---|---|---|
flagKey | string | Preview flag slug | Yes |
mood | enum | One of: VERY_SAD, SAD, NEUTRAL, HAPPY, VERY_HAPPY | Yes |
rating | number | Integer from 1 to 5 | Yes |
description | string | Optional feedback details (max 2000 chars) | No |
metadata | object | Optional unstructured key/value data for custom context | No |
Example Request:
curl -X POST "https://flags-api.basestack.co/v1/flags/preview/feedback" \
-H "Content-Type: application/json" \
-H "x-project-key: your-project-key" \
-H "x-environment-key: your-environment-key" \
-d '{
"flagKey": "landing-preview",
"mood": "HAPPY",
"rating": 4,
"description": "The new copy feels clearer and more direct.",
"metadata": {
"source": "landing-page",
"sessionId": "abc123"
}
}'const response = await fetch('https://flags-api.basestack.co/v1/flags/preview/feedback', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-project-key': 'your-project-key',
'x-environment-key': 'your-environment-key',
},
body: JSON.stringify({
flagKey: 'landing-preview',
mood: 'HAPPY',
rating: 4,
description: 'The new copy feels clearer and more direct.',
metadata: {
source: 'landing-page',
sessionId: 'abc123',
},
}),
});
const data = await response.json();
console.log(data);import requests
headers = {
'Content-Type': 'application/json',
'x-project-key': 'your-project-key',
'x-environment-key': 'your-environment-key',
}
payload = {
'flagKey': 'landing-preview',
'mood': 'HAPPY',
'rating': 4,
'description': 'The new copy feels clearer and more direct.',
'metadata': {
'source': 'landing-page',
'sessionId': 'abc123',
},
}
response = requests.post(
'https://flags-api.basestack.co/v1/flags/preview/feedback',
headers=headers,
json=payload
)
data = response.json()
print(data)<?php
$headers = [
'Content-Type: application/json',
'x-project-key: your-project-key',
'x-environment-key: your-environment-key',
];
$payload = json_encode([
'flagKey' => 'landing-preview',
'mood' => 'HAPPY',
'rating' => 4,
'description' => 'The new copy feels clearer and more direct.',
'metadata' => [
'source' => 'landing-page',
'sessionId' => 'abc123',
],
]);
$ch = curl_init('https://flags-api.basestack.co/v1/flags/preview/feedback');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$data = json_decode($response, true);
print_r($data);
curl_close($ch);Response Codes:
| Status Code | Description |
|---|---|
201 | Success - Feedback submitted |
404 | Preview flag not found |
400 | Validation error or server error |
Success Response (201):
{
"success": true,
"feedbackId": "clz123abc456"
}Error Response (404):
{
"error": true,
"message": "Preview flag with key landing-preview does not exist"
}Error Response (400):
{
"error": true,
"message": "Something went wrong, please try again later."
}Submit code references
Upload or sync code references for feature flags (for example from a static analysis tool or CI). References are keyed by flag slug; each upload replaces stored references for the given branch and the flag slugs included in the payload rows that are no longer reported for that branch are removed.
Endpoint: POST /flags/code-refs
Headers:
| Header | Type | Description | Required |
|---|---|---|---|
x-project-key | string | Your project identifier | Yes |
x-environment-key | string | Your environment identifier | Yes |
x-api-key | string | Project API token (create under project settings) | Yes |
Request Body:
| Field | Type | Description | Required |
|---|---|---|---|
branch | string | Git branch name (max 255 chars) | Yes |
projectName | string | Display name for the project/repo context (max 150 chars) | Yes |
repositoryUrl | string | Repository URL (max 255 chars) | No |
references | object | Map of flag slug → array of reference rows (each slug max 150 chars) | Yes |
Each item in the arrays under references has:
| Field | Type | Description | Required |
|---|---|---|---|
filePath | string | Path to the file (max 2000 chars) | Yes |
lineNumber | number | Positive integer line number | Yes |
lineContent | string | Line content snapshot (max 4000 chars) | Yes |
Example Request:
curl -X POST "https://flags-api.basestack.co/v1/flags/code-refs" \
-H "Content-Type: application/json" \
-H "x-project-key: your-project-key" \
-H "x-environment-key: your-environment-key" \
-H "x-api-key: your-project-api-token" \
-d '{
"branch": "main",
"projectName": "acme-web",
"repositoryUrl": "https://github.com/acme/web",
"references": {
"new-checkout": [
{
"filePath": "src/features/checkout.tsx",
"lineNumber": 42,
"lineContent": "if (flags.newCheckout) {"
}
]
}
}'const response = await fetch('https://flags-api.basestack.co/v1/flags/code-refs', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-project-key': 'your-project-key',
'x-environment-key': 'your-environment-key',
'x-api-key': 'your-project-api-token',
},
body: JSON.stringify({
branch: 'main',
projectName: 'acme-web',
repositoryUrl: 'https://github.com/acme/web',
references: {
'new-checkout': [
{
filePath: 'src/features/checkout.tsx',
lineNumber: 42,
lineContent: 'if (flags.newCheckout) {',
},
],
},
}),
});
const data = await response.json();
console.log(data);import requests
headers = {
'Content-Type': 'application/json',
'x-project-key': 'your-project-key',
'x-environment-key': 'your-environment-key',
'x-api-key': 'your-project-api-token',
}
payload = {
'branch': 'main',
'projectName': 'acme-web',
'repositoryUrl': 'https://github.com/acme/web',
'references': {
'new-checkout': [
{
'filePath': 'src/features/checkout.tsx',
'lineNumber': 42,
'lineContent': 'if (flags.newCheckout) {',
},
],
},
}
response = requests.post(
'https://flags-api.basestack.co/v1/flags/code-refs',
headers=headers,
json=payload,
)
data = response.json()
print(data)<?php
$headers = [
'Content-Type: application/json',
'x-project-key: your-project-key',
'x-environment-key: your-environment-key',
'x-api-key: your-project-api-token',
];
$payload = json_encode([
'branch' => 'main',
'projectName' => 'acme-web',
'repositoryUrl' => 'https://github.com/acme/web',
'references' => [
'new-checkout' => [
[
'filePath' => 'src/features/checkout.tsx',
'lineNumber' => 42,
'lineContent' => 'if (flags.newCheckout) {',
],
],
],
]);
$ch = curl_init('https://flags-api.basestack.co/v1/flags/code-refs');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$data = json_decode($response, true);
print_r($data);
curl_close($ch);Response Codes:
| Status Code | Description |
|---|---|
201 | Success - Code references updated |
401 | Missing or invalid x-api-key |
404 | Environment not found for the given keys |
400 | Validation error or server error |
Success Response (201):
{
"success": true,
"message": "Code references updated successfully"
}Error Response (401):
When x-api-key is missing or invalid. If the header is omitted, the message is typically Missing required header: x-api-key. If the token is invalid, the message may be Invalid API Key or another detail from the key verifier.
{
"error": true,
"message": "Missing required header: x-api-key"
}Error Response (404):
When the environment does not exist for the project:
{
"error": true,
"message": "Environment with key your-environment-key does not exist"
}Error Response (400):
When validation fails or a server error occurs:
{
"error": true,
"message": "Something went wrong, please try again later."
}Error Handling
Common Error Responses
Server Error (400)
When a server error occurs or the request is invalid:
{
"error": true,
"message": "Something went wrong, please try again later."
}Common causes:
- Database connection issues
- Invalid request format
- Internal server errors
Solution: Retry the request after a short delay. If the issue persists, check your request format and authentication headers.
Flag Not Found (404)
When requesting a specific flag that doesn't exist:
{
"enabled": false,
"error": true,
"message": "Flag with slug header does not exist"
}Solution: Verify the flag slug exists in your environment. Check your Basestack dashboard to see available flags.
Preview Flag Not Found (404)
When submitting feedback for a preview flag that doesn't exist:
{
"error": true,
"message": "Preview flag with key landing-preview does not exist"
}Solution: Verify flagKey matches an existing preview flag slug in the same project and environment.
The 404 response includes enabled: false to allow your application to handle missing flags gracefully. You can treat this as a disabled flag rather than an error condition.
Best Practices for Error Handling
- Always check response status codes before processing the response body
- Handle missing flags gracefully - Use the
enabled: falseresponse as a fallback - Implement retry logic for network errors (5xx status codes)
- Cache responses to reduce API calls and handle temporary failures
- Log errors for debugging and monitoring
Example Error Handling:
async function getFlagSafely(slug, projectKey, environmentKey) {
try {
const response = await fetch(
`https://flags-api.basestack.co/v1/flags/${slug}`,
{
headers: {
'x-project-key': projectKey,
'x-environment-key': environmentKey,
},
}
);
const data = await response.json();
// Handle 404 - flag doesn't exist
if (response.status === 404) {
// API returns { enabled: false, error: true, message: "..." }
return { enabled: false, error: true };
}
// Handle 400 - server error
if (response.status === 400) {
console.error('API error:', data.message);
return { enabled: false, error: true };
}
// Success - return flag object
if (response.ok) {
return data; // Flag object directly
}
throw new Error(`Unexpected status: ${response.status}`);
} catch (error) {
console.error('Failed to fetch flag:', error);
// Return safe default
return { enabled: false, error: true };
}
}Response Schema
Flag Object
The flag object structure varies slightly depending on the endpoint:
GET /flags/:slug returns:
| Property | Type | Description |
|---|---|---|
slug | string | Unique identifier for the flag |
enabled | boolean | Whether the flag is currently enabled |
payload | object | null | Optional JSON data associated with the flag |
expiredAt | string | null | ISO 8601 date string when the flag expires (if applicable) |
description | string | Human-readable description of the flag |
GET /flags returns flags with additional fields:
| Property | Type | Description |
|---|---|---|
slug | string | Unique identifier for the flag |
enabled | boolean | Whether the flag is currently enabled |
payload | object | null | Optional JSON data associated with the flag |
expiredAt | string | null | ISO 8601 date string when the flag expires (if applicable) |
description | string | Human-readable description of the flag |
createdAt | string | ISO 8601 date string when the flag was created |
updatedAt | string | ISO 8601 date string when the flag was last updated |
GET /flags/preview returns:
| Property | Type | Description |
|---|---|---|
slug | string | Unique identifier for the preview flag |
enabled | boolean | Whether the preview flag is currently enabled |
isPreview | boolean | Indicates this is a preview flag (true) |
previewName | string | null | Human-readable name for the preview |
previewContent | string | HTML content generated from stored Lexical JSON |
expiredAt | string | null | ISO 8601 date string when the preview flag expires (if applicable) |
createdAt | string | ISO 8601 date string when the preview flag was created |
POST /flags/preview/feedback request body:
| Property | Type | Description |
|---|---|---|
flagKey | string | Preview flag slug |
mood | "VERY_SAD" | "SAD" | "NEUTRAL" | "HAPPY" | "VERY_HAPPY" | Sentiment label |
rating | number | Integer rating from 1 to 5 |
description | string | undefined | Optional feedback details, max 2000 characters |
metadata | Record<string, unknown> | undefined | Optional unstructured key/value data |
POST /flags/preview/feedback success response:
| Property | Type | Description |
|---|---|---|
success | boolean | true when feedback is stored |
feedbackId | string | Unique identifier of the feedback record |
POST /flags/code-refs request body:
| Property | Type | Description |
|---|---|---|
branch | string | Branch name (1–255 chars) |
projectName | string | Project/repo label (1–150 chars) |
repositoryUrl | string | undefined | Optional repository URL (max 255 chars) |
references | Record<string, CodeReferenceRow[]> | Flag slug → list of file references (each slug max 150 chars; each list non-empty) |
Where CodeReferenceRow is:
| Property | Type | Description |
|---|---|---|
filePath | string | File path (1–2000 chars) |
lineNumber | number | Positive integer |
lineContent | string | Line text (1–4000 chars) |
POST /flags/code-refs success response:
| Property | Type | Description |
|---|---|---|
success | boolean | true when references were processed |
message | string | Confirmation message |
Error Response Fields:
| Property | Type | Description |
|---|---|---|
error | boolean | Whether an error occurred (always true in error responses) |
message | string | Error message describing what went wrong |
enabled | boolean | Always false in 404 responses (flag not found) |
TypeScript Type Definition
For TypeScript projects, use these type definitions:
// Flag object returned by GET /flags/:slug
export interface Flag {
slug: string;
enabled: boolean;
payload?: unknown | null;
expiredAt?: string | null;
description: string;
}
// Flag object returned by GET /flags (includes timestamps)
export interface FlagWithTimestamps extends Flag {
createdAt: string;
updatedAt: string;
}
// Response from GET /flags
export interface FlagsResponse {
flags: FlagWithTimestamps[];
}
// Preview flag object returned by GET /flags/preview
export interface PreviewFlag {
slug: string;
enabled: boolean;
isPreview: true;
previewName?: string | null;
previewContent: string;
expiredAt?: string | null;
createdAt: string;
}
// Response from GET /flags/preview
export interface PreviewFlagsResponse {
flags: PreviewFlag[];
}
// Request body for POST /flags/preview/feedback
export interface PreviewFeedbackRequest {
flagKey: string;
mood: 'VERY_SAD' | 'SAD' | 'NEUTRAL' | 'HAPPY' | 'VERY_HAPPY';
rating: 1 | 2 | 3 | 4 | 5;
description?: string;
metadata?: Record<string, unknown>;
}
// Success response from POST /flags/preview/feedback
export interface PreviewFeedbackResponse {
success: true;
feedbackId: string;
}
// Request body for POST /flags/code-refs
export interface CodeReferenceRow {
filePath: string;
lineNumber: number;
lineContent: string;
}
export interface CodeReferencesRequest {
branch: string;
projectName: string;
repositoryUrl?: string;
references: Record<string, CodeReferenceRow[]>;
}
// Success response from POST /flags/code-refs
export interface CodeReferencesResponse {
success: true;
message: string;
}
// Error response
export interface ErrorResponse {
error: true;
message: string;
enabled?: boolean; // Present in 404 responses
}Caching
All GET endpoints include cache headers to optimize performance:
Cache-Control: public, s-maxage=60, max-age=30, stale-while-revalidate=60, stale-if-error=300This means:
- CDN/Edge Cache: 60 seconds (
s-maxage) - Browser Cache: 30 seconds (
max-age) - Stale While Revalidate: Serve stale content for up to 60 seconds while fetching fresh data
- Stale If Error: Serve stale content for up to 5 minutes if the origin server errors
The API uses aggressive caching to reduce load and improve response times. If you need fresh flag data immediately, you may need to bypass the cache or wait for the cache to expire.
Rate Limiting
API rate limits may apply depending on your plan. Check your dashboard for current rate limit information. If you exceed rate limits, you'll receive a 429 Too Many Requests response.
Common Use Cases
Preloading Flags on Application Start
Fetch all flags when your application initializes:
async function preloadFlags(projectKey, environmentKey) {
const response = await fetch('https://flags-api.basestack.co/v1/flags', {
headers: {
'x-project-key': projectKey,
'x-environment-key': environmentKey,
},
});
const { flags } = await response.json();
// Cache flags for use throughout your application
return flags.reduce((cache, flag) => {
cache[flag.slug] = flag;
return cache;
}, {});
}Checking a Flag Before Rendering
Check a flag before rendering a feature:
async function shouldShowFeature(featureSlug, projectKey, environmentKey) {
const response = await fetch(
`https://flags-api.basestack.co/v1/flags/${featureSlug}`,
{
headers: {
'x-project-key': projectKey,
'x-environment-key': environmentKey,
},
}
);
const flag = await response.json();
return flag.enabled && !flag.error;
}