API Reference

Overview

The IntelliToggle API is a REST API that enables you to manage feature flags, projects, tenants, and user access programmatically. This reference covers all available endpoints, request/response formats, and authentication methods.

Base Information

Base URL

https://api.intellitoggle.com/

API Version

1.0.0

Protocol

HTTPS

Authentication

Bearer Token (JWT)

Rate Limiting

Yes (see response headers)

Response Headers

All successful API responses include rate limiting information:

  • RateLimit-Limit - Maximum requests allowed

  • RateLimit-Remaining - Remaining requests in current window

  • RateLimit-Reset - Time when rate limit resets

Authentication

Bearer Authentication

Most endpoints require authentication using JWT bearer tokens.

Authorization: Bearer <your-jwt-token>

OAuth 2.0

For machine-to-machine authentication, use OAuth 2.0 client credentials flow.

POST /oauth/token

Exchange client credentials for an access token.

Request Body (application/x-www-form-urlencoded):

grant_type=client_credentials
client_id=<your-client-id>
client_secret=<your-client-secret>
scope=flags:read flags:write

Response:

{
  "access_token": "eyJhbGc...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "flags:read flags:write"
}

User Authentication

POST /auth/signin

Authenticate with email and password.

Request Body:

{
  "email": "user@example.com",
  "password": "securepassword"
}

Response (200 OK):

{
  "token": "eyJhbGc...",
  "refreshToken": "refresh_token_value",
  "expiresIn": 3600,
  "user": {
    "id": "user_123",
    "email": "user@example.com",
    "displayName": "John Doe",
    "role": "admin"
  }
}

POST /auth/signup

Create a new user account.

Request Body:

{
  "email": "newuser@example.com",
  "password": "securepassword123",
  "displayName": "John Doe"
}

Response (201 Created): Returns same structure as signin endpoint.

POST /auth/google

Authenticate using Google ID token.

Request Body:

{
  "idToken": "google_id_token_here"
}

POST /auth/microsoft

Authenticate using Microsoft ID token.

Request Body:

{
  "idToken": "microsoft_id_token_here"
}

POST /auth/forgot-password

Send password reset email.

Request Body:

{
  "email": "user@example.com"
}

POST /auth/update-password

Update user password (requires authentication).

Request Body:

{
  "currentPassword": "oldpassword",
  "newPassword": "newpassword123"
}

POST /auth/logout

Logout current user session.

Response (200 OK):

{
  "success": true
}

Feature Flags

GET /api/flags

List all feature flags for tenant.

Headers: * X-Tenant-ID (required) - Tenant identifier * X-Environment (optional, default: production) - Environment name

Response (200 OK):

[
  {
    "id": "flag_123",
    "key": "new-checkout-flow",
    "name": "New Checkout Flow",
    "type": "boolean",
    "enabled": true,
    "defaultValue": false,
    "description": "Enable the new checkout flow",
    "tags": ["ui", "checkout"],
    "projectId": "proj_456",
    "createdAt": "2024-01-15T10:00:00Z",
    "updatedAt": "2024-01-20T15:30:00Z"
  }
]

POST /api/flags

Create a new feature flag.

Headers: * X-Tenant-ID (required) * X-Environment (optional, default: production)

Request Body:

{
  "key": "new-checkout-flow",
  "name": "New Checkout Flow",
  "type": "boolean",
  "defaultValue": false,
  "description": "Enable the new checkout flow",
  "tags": ["ui", "checkout"]
}

Flag Types: * boolean - True/false values * string - Text values * number - Numeric values * json - Complex JSON objects

Response (201 Created): Returns the created flag object.

GET /api/flags/{flagKey}

Get specific feature flag details.

Path Parameters: * flagKey - Unique flag identifier

Headers: * X-Tenant-ID (required) * X-Environment (optional)

PATCH /api/flags/{flagKey}

Update feature flag details.

Request Body:

{
  "name": "Updated Name",
  "description": "Updated description",
  "defaultValue": true,
  "tags": ["new-tag"]
}

DELETE /api/flags/{flagKey}

Delete a feature flag.

Response (204 No Content): No response body.

POST /api/flags/{flagKey}/enable

Enable a feature flag.

Response (200 OK):

{
  "success": true
}

POST /api/flags/{flagKey}/disable

Disable a feature flag.

POST /api/flags/{flagKey}/evaluate

Evaluate a feature flag for specific user context.

Request Body:

{
  "userId": "user_123",
  "attributes": {
    "email": "user@example.com",
    "plan": "premium",
    "country": "US"
  },
  "environment": "production"
}

Response (200 OK):

{
  "enabled": true,
  "value": true,
  "reason": "RULE_MATCH"
}

GET /api/flags/{flagKey}/history

Get change history for a feature flag.

Response (200 OK):

[
  {
    "id": "hist_123",
    "action": "enabled",
    "changes": {
      "enabled": {
        "from": false,
        "to": true
      }
    },
    "userId": "user_456",
    "userName": "John Doe",
    "timestamp": "2024-01-20T15:30:00Z"
  }
]

Flag Variations

GET /api/flags/{flagKey}/variations

List all variations for a feature flag.

Response (200 OK):

[
  {
    "id": "var_123",
    "name": "Control",
    "value": false,
    "description": "Control group",
    "weight": 50
  },
  {
    "id": "var_456",
    "name": "Treatment",
    "value": true,
    "description": "Treatment group",
    "weight": 50
  }
]

POST /api/flags/{flagKey}/variations

Add new variation to feature flag.

Request Body:

{
  "name": "New Variation",
  "value": true,
  "description": "Description of variation"
}

PATCH /api/flags/{flagKey}/variations/{variationId}

Update existing flag variation.

DELETE /api/flags/{flagKey}/variations/{variationId}

Delete flag variation.

Projects

GET /api/projects

List all projects in tenant.

Headers: * X-Tenant-ID (required)

Response (200 OK):

[
  {
    "id": "proj_123",
    "name": "Mobile App Features",
    "description": "Feature flags for mobile application",
    "color": "#6366f1",
    "flagCount": 15,
    "createdAt": "2024-01-01T00:00:00Z",
    "updatedAt": "2024-01-20T12:00:00Z"
  }
]

POST /api/projects

Create a new project.

Request Body:

{
  "name": "Mobile App Features",
  "description": "Feature flags for mobile application",
  "color": "#6366f1"
}

Response (201 Created): Returns the created project object.

GET /api/projects/{projectId}

Get specific project details.

PATCH /api/projects/{projectId}

Update project details.

Request Body:

{
  "name": "Updated Project Name",
  "description": "Updated description",
  "color": "#ef4444"
}

DELETE /api/projects/{projectId}

Delete a project.

Project Flags

GET /api/flags/projects/{projectId}/flags

List all flags within a specific project.

POST /api/flags/projects/{projectId}/flags

Create a new flag within a project.

Request Body:

{
  "key": "test-feature1",
  "name": "Test Feature1",
  "type": "boolean",
  "defaultValue": false,
  "description": "Test flag",
  "flag_variations": [
    {
      "name": "Enabled",
      "value": true,
      "description": "Feature enabled state"
    },
    {
      "name": "Disabled",
      "value": false,
      "description": "Feature disabled state"
    }
  ]
}

GET /api/flags/projects/{projectId}/flags/{flagKey}

Get specific flag within a project.

PATCH /api/flags/projects/{projectId}/flags/{flagKey}

Update flag within a project.

Request Body:

{
  "status": "active",
  "name": "Updated Name",
  "description": "Updated description"
}

Status Values: * active - Flag is active * inactive - Flag is inactive * archived - Flag is archived

DELETE /api/flags/projects/{projectId}/flags/{flagKey}

Delete flag from project.

POST /api/flags/projects/{projectId}/flags/{flagKey}/enable

Enable flag within project.

POST /api/flags/projects/{projectId}/flags/{flagKey}/disable

Disable flag within project.

Tenants

GET /api/tenants

List all tenants for current user.

Response (200 OK):

[
  {
    "id": "tenant_123",
    "name": "Acme Corporation",
    "primaryEmail": "admin@acme.com",
    "contactName": "John Doe",
    "isSandbox": false,
    "subscription": {
      "plan": "premium",
      "status": "active"
    },
    "createdAt": "2024-01-01T00:00:00Z"
  }
]

POST /api/tenants

Create a new tenant organization.

Request Body:

{
  "name": "Acme Corporation",
  "primaryEmail": "admin@acme.com",
  "contactName": "John Doe",
  "isSandbox": false
}

GET /api/tenants/{tenantId}

Get specific tenant details.

Headers: * X-Tenant-ID (required)

PATCH /api/tenants/{tenantId}

Update tenant information.

Request Body:

{
  "name": "Updated Name",
  "primaryEmail": "newemail@acme.com",
  "contactName": "Jane Smith"
}

DELETE /api/tenants/{tenantId}

Delete a tenant.

GET /api/tenants/{tenantId}/usage

Get tenant resource usage statistics.

Response (200 OK):

{
  "flags": 50,
  "evaluations": 1000000,
  "users": 10
}

Tenant Environments

GET /api/tenants/{tenantId}/environments

List all environments in tenant.

Response (200 OK):

["production", "staging", "development"]

POST /api/tenants/{tenantId}/environments

Add new environment to tenant.

Request Body:

{
  "environment": "qa"
}

DELETE /api/tenants/{tenantId}/environments/{environment}

Remove environment from tenant.

Tenant Users

GET /api/tenants/{tenantId}/users

List all users in tenant.

Response (200 OK):

[
  {
    "userId": "user_123",
    "email": "john@example.com",
    "displayName": "John Doe",
    "role": "admin",
    "lastAccessedAt": "2024-01-20T15:30:00Z",
    "createdAt": "2024-01-01T00:00:00Z"
  }
]

POST /api/tenants/{tenantId}/users

Add user to tenant with specific role.

Request Body:

{
  "email": "newuser@example.com",
  "role": "developer"
}

Available Roles: * admin - Full access to all features * developer - Can manage flags and projects * viewer - Read-only access

DELETE /api/tenants/{tenantId}/users/{userId}

Remove user from tenant.

Billing

POST /api/billing/checkout

Create Stripe checkout session for subscription.

Headers: * X-Tenant-ID (required)

Request Body:

{
  "type": "subscription",
  "planId": "standard",
  "successUrl": "https://app.intellitoggle.com/success",
  "cancelUrl": "https://app.intellitoggle.com/cancel"
}

Available Plans: * free - Free tier * standard - Standard plan * premium - Premium plan

Response (200 OK):

{
  "url": "https://checkout.stripe.com/..."
}

POST /api/billing/portal

Create Stripe customer portal session.

Request Body:

{
  "returnUrl": "https://app.intellitoggle.com/billing"
}

GET /api/billing/subscription

Get current subscription information.

Response (200 OK):

{
  "id": "sub_123",
  "plan": "premium",
  "status": "active",
  "currentPeriodStart": "2024-01-01T00:00:00Z",
  "currentPeriodEnd": "2024-02-01T00:00:00Z",
  "cancelAtPeriodEnd": false
}

GET /api/billing/features/analytics

Check if tenant has access to analytics features.

Response (200 OK):

{
  "hasAccess": true
}

GET /api/billing/features/experiments/check

Check if tenant has access to A/B testing features.

GET /api/billing/features/multivariate/check

Check if tenant has access to multivariate testing.

OAuth Clients

POST /api/oauth/clients

Create new OAuth client for API access.

Headers: * X-Tenant-ID (required)

Request Body:

{
  "name": "SDK Demo",
  "scopes": [
    "flags:read",
    "flags:write",
    "flags:evaluate",
    "projects:read",
    "projects:write"
  ]
}

Available Scopes: * flags:read - Read flag data * flags:write - Create and modify flags * flags:evaluate - Evaluate flags * projects:read - Read project data * projects:write - Create and modify projects

Response (201 Created):

{
  "clientId": "client_abc123",
  "clientSecret": "secret_xyz789",
  "name": "SDK Demo",
  "scopes": ["flags:read", "flags:write"],
  "createdAt": "2024-01-20T10:00:00Z"
}
Store the clientSecret securely. It will only be shown once.

Product Tours

GET /v1/users/{userId}/product-tours/{tourKey}

Get the status of a product tour for a user.

Path Parameters: * userId - User identifier (e.g., usr_123) * tourKey - Tour identifier (e.g., main-onboarding@v1)

Response (200 OK):

{
  "completed": false,
  "completed_at": null,
  "created_at": "2024-01-15T10:00:00Z",
  "updated_at": "2024-01-20T15:30:00Z"
}

PUT /v1/users/{userId}/product-tours/{tourKey}

Update the completion status of a product tour.

Headers: * Idempotency-Key (optional) - Ensure idempotent requests

Request Body:

{
  "completed": true,
  "completed_at": "2024-01-20T15:30:00Z"
}

DELETE /v1/users/{userId}/product-tours/{tourKey}

Reset product tour status to allow user to see it again.

Sandbox

GET /api/sandbox/status

Get current sandbox environment status.

Headers: * X-Tenant-ID (required)

Response (200 OK):

{
  "active": true,
  "expiresAt": "2024-02-01T00:00:00Z"
}

GET /api/sandbox/indicators

Get sandbox usage indicators and metrics.

Response (200 OK):

{
  "flagsUsed": 5,
  "evaluations": 1000
}

GET /api/sandbox/demo-data

Get demo data for sandbox environment.

Response (200 OK):

{
  "flags": ["demo-flag-1", "demo-flag-2"],
  "users": ["demo-user-1", "demo-user-2"]
}

POST /api/sandbox/cleanup/tenant

Reset sandbox tenant to clean state.

Response (200 OK):

{
  "success": true
}

POST /api/sandbox/subscribe

Subscribe to sandbox environment updates.

Request Body:

{
  "email": "user@example.com",
  "name": "John Doe"
}

Admin Endpoints

GET /admin/users

List all users across the platform (admin only).

Response (200 OK): Returns array of user objects.

POST /admin/invite

Send invitation to new user (admin only).

Request Body:

{
  "email": "newuser@company.com",
  "role": "user"
}

Available Roles: * admin - Administrator * user - Regular user

GET /tenants

List all tenants (admin only).

Health & System

GET /health

Check API health status.

Response (200 OK):

{
  "status": "healthy",
  "timestamp": "2024-01-20T15:30:00Z"
}

GET /version

Get current API version.

Response (200 OK):

{
  "version": "1.0.0",
  "buildDate": "2024-01-15T10:00:00Z"
}

GET /

Basic API information.

Response (200 OK):

{
  "name": "IntelliToggle API",
  "version": "1.0.0"
}

Error Responses

All error responses follow RFC 9457 (Problem Details).

Error Structure

{
  "type": "https://docs.example.com/errors/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "The requested resource was not found.",
  "instance": "req_01Hh88888"
}

Common Status Codes

Code Description

200

Success

201

Created

204

No Content

400

Bad Request - Invalid input

401

Unauthorized - Authentication required

403

Forbidden - Access denied

404

Not Found - Resource doesn’t exist

409

Conflict - Resource already exists

412

Precondition Failed

415

Unsupported Media Type

422

Unprocessable Entity - Validation failed

429

Too Many Requests - Rate limit exceeded

500

Internal Server Error

503

Service Unavailable

Validation Errors

Validation errors (422) include detailed field-level information:

{
  "type": "https://docs.example.com/errors/unprocessable-entity",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "Validation failed.",
  "errors": {
    "email": "Invalid email format",
    "password": "Password must be at least 8 characters"
  }
}

Rate Limiting

All endpoints are subject to rate limiting. Limits vary by subscription plan.

When rate limit is exceeded, you’ll receive a 429 response:

{
  "type": "https://docs.example.com/errors/too-many-requests",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Rate limit exceeded. Try again later."
}

Check response headers for rate limit information:

  • RateLimit-Limit - Maximum requests allowed

  • RateLimit-Remaining - Remaining requests

  • RateLimit-Reset - Reset time

Best Practices

Use Idempotency Keys

For critical operations (like creating subscriptions), use idempotency keys to prevent duplicate requests:

Idempotency-Key: unique-request-id-123

Handle Errors Gracefully

Always check status codes and handle errors appropriately. Don’t assume success.

Respect Rate Limits

Monitor RateLimit-Remaining header and implement exponential backoff when approaching limits.

Use Specific Scopes

When creating OAuth clients, request only the scopes you need. Follow the principle of least privilege.

Secure API Keys

  • Never commit API keys to version control

  • Rotate keys regularly

  • Use environment variables for key storage

  • Implement key rotation without downtime

Code Examples

cURL

# Create a feature flag
curl -X POST https://api.intellitoggle.com/api/flags \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Tenant-ID: tenant_123" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "new-feature",
    "name": "New Feature",
    "type": "boolean",
    "defaultValue": false
  }'