3 REST API Reference
Insidious Fiddler edited this page 2026-02-06 21:04:12 +00:00

REST API Reference

Base URL: https://hoist.example.com/api/v1

Response Format

All responses follow this format:

{
  "success": true,
  "data": { ... },
  "meta": {
    "page": 1,
    "perPage": 20,
    "total": 100,
    "totalPages": 5
  }
}

Error responses:

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Resource not found",
    "details": { ... }
  }
}

Error Codes

Code HTTP Status Description
BAD_REQUEST 400 Invalid request
UNAUTHORIZED 401 Missing/invalid auth
FORBIDDEN 403 Insufficient permissions
NOT_FOUND 404 Resource not found
CONFLICT 409 Resource conflict
VALIDATION_ERROR 422 Validation failed
RATE_LIMITED 429 Rate limit exceeded
INTERNAL_ERROR 500 Server error

Authentication Endpoints

Login

POST /auth/login
{
  "email": "user@example.com",
  "password": "password",
  "mfaCode": "123456"  // Optional, if MFA enabled
}

Response:

{
  "success": true,
  "data": {
    "accessToken": "eyJ...",
    "refreshToken": "eyJ...",
    "expiresIn": 900,
    "user": { "id": "...", "email": "...", "name": "..." }
  }
}

Refresh Token

POST /auth/refresh
{
  "refreshToken": "eyJ..."
}

Logout

POST /auth/logout
Authorization: Bearer <token>

Register

POST /auth/register
{
  "email": "user@example.com",
  "password": "secure-password",
  "name": "John Doe"
}

Current User

GET /auth/me
Authorization: Bearer <token>

Organizations

List Organizations

GET /organizations
Authorization: Bearer <token>

Create Organization

POST /organizations
Authorization: Bearer <token>
{
  "name": "My Company",
  "slug": "my-company"
}

Get Organization

GET /organizations/{orgId}
Authorization: Bearer <token>

Update Organization

PATCH /organizations/{orgId}
Authorization: Bearer <token>
{
  "name": "New Name"
}

Delete Organization

DELETE /organizations/{orgId}
Authorization: Bearer <token>

Projects

List Projects

GET /organizations/{orgId}/projects
Authorization: Bearer <token>

Create Project

POST /organizations/{orgId}/projects
Authorization: Bearer <token>
{
  "name": "Web App",
  "key": "web-app",
  "description": "Main web application"
}

Get Project

GET /projects/{projectId}
Authorization: Bearer <token>

Update Project

PATCH /projects/{projectId}
Authorization: Bearer <token>

Delete Project

DELETE /projects/{projectId}
Authorization: Bearer <token>

Environments

List Environments

GET /projects/{projectId}/environments
Authorization: Bearer <token>

Create Environment

POST /projects/{projectId}/environments
Authorization: Bearer <token>
{
  "name": "Production",
  "key": "production",
  "color": "#10b981"
}

Update Environment

PATCH /environments/{envId}
Authorization: Bearer <token>

Delete Environment

DELETE /environments/{envId}
Authorization: Bearer <token>

Flags

List Flags

GET /projects/{projectId}/flags
Authorization: Bearer <token>

Query parameters:

  • page - Page number (default: 1)
  • perPage - Items per page (default: 20)
  • search - Search by key or name
  • type - Filter by type (boolean, string, number, json)
  • status - Filter by status (active, deprecated, archived)

Create Flag

POST /projects/{projectId}/flags
Authorization: Bearer <token>
{
  "key": "new-checkout",
  "name": "New Checkout Flow",
  "description": "Enable the redesigned checkout",
  "type": "boolean",
  "defaultValue": false,
  "tags": ["checkout", "experiment"]
}

Get Flag

GET /flags/{flagId}
Authorization: Bearer <token>

Update Flag

PATCH /flags/{flagId}
Authorization: Bearer <token>
{
  "name": "Updated Name",
  "description": "Updated description",
  "tags": ["new-tag"]
}

Delete Flag

DELETE /flags/{flagId}
Authorization: Bearer <token>

Get Flag Configuration

GET /flags/{flagId}/environments/{envId}
Authorization: Bearer <token>

Update Flag Configuration

PATCH /flags/{flagId}/environments/{envId}
Authorization: Bearer <token>
{
  "enabled": true,
  "defaultValue": true,
  "rules": [
    {
      "priority": 1,
      "conditions": [
        {
          "attribute": "plan",
          "operator": "equals",
          "value": "enterprise"
        }
      ],
      "value": true
    }
  ]
}

SDK Endpoints

Get Flag Config (Server Keys)

GET /flags/config
X-API-Key: hoist_live_xxx

Response:

{
  "success": true,
  "data": {
    "flags": [
      {
        "key": "new-checkout",
        "type": "boolean",
        "enabled": true,
        "defaultValue": false,
        "rules": [ ... ],
        "version": 5
      }
    ],
    "segments": [
      {
        "key": "beta-testers",
        "rules": [ ... ]
      }
    ]
  }
}

Evaluate Flag (Client Keys)

POST /evaluate
X-API-Key: hoist_pk_xxx
{
  "flagKey": "new-checkout",
  "context": {
    "targetingKey": "user-123",
    "attributes": {
      "plan": "pro"
    }
  }
}

Response:

{
  "success": true,
  "data": {
    "value": true,
    "variant": "enabled",
    "reason": "TARGETING_MATCH",
    "version": 5
  }
}

Batch Evaluate

POST /evaluate/batch
X-API-Key: hoist_pk_xxx
{
  "flags": ["flag1", "flag2", "flag3"],
  "context": {
    "targetingKey": "user-123",
    "attributes": { "plan": "pro" }
  }
}

Segments

List Segments

GET /projects/{projectId}/segments
Authorization: Bearer <token>

Create Segment

POST /projects/{projectId}/segments
Authorization: Bearer <token>
{
  "key": "beta-testers",
  "name": "Beta Testers",
  "description": "Users in beta program",
  "rules": [
    {
      "attribute": "betaTester",
      "operator": "equals",
      "value": true
    }
  ]
}

Update Segment

PATCH /segments/{segmentId}
Authorization: Bearer <token>

Delete Segment

DELETE /segments/{segmentId}
Authorization: Bearer <token>

API Keys

List API Keys

GET /projects/{projectId}/api-keys
Authorization: Bearer <token>

Create API Key

POST /projects/{projectId}/api-keys
Authorization: Bearer <token>
{
  "name": "Production Server",
  "type": "server",
  "environment": "production"
}

Response includes the full key (only shown once):

{
  "success": true,
  "data": {
    "id": "...",
    "name": "Production Server",
    "key": "hoist_live_xxxxxxxxxxxxx",
    "type": "server",
    "environment": "production",
    "createdAt": "2024-01-01T00:00:00Z"
  }
}

Delete API Key

DELETE /api-keys/{keyId}
Authorization: Bearer <token>

Webhooks

List Webhooks

GET /projects/{projectId}/webhooks
Authorization: Bearer <token>

Create Webhook

POST /projects/{projectId}/webhooks
Authorization: Bearer <token>
{
  "url": "https://example.com/webhook",
  "events": ["flag.updated", "flag.created"],
  "secret": "webhook-secret"
}

Update Webhook

PATCH /webhooks/{webhookId}
Authorization: Bearer <token>

Delete Webhook

DELETE /webhooks/{webhookId}
Authorization: Bearer <token>

Audit Log

List Audit Events

GET /organizations/{orgId}/audit
Authorization: Bearer <token>

Query parameters:

  • page - Page number
  • perPage - Items per page
  • action - Filter by action type
  • userId - Filter by user
  • resourceType - Filter by resource type
  • from - Start date (ISO 8601)
  • to - End date (ISO 8601)

Response:

{
  "success": true,
  "data": [
    {
      "id": "...",
      "action": "flag.updated",
      "resourceType": "flag",
      "resourceId": "...",
      "userId": "...",
      "userName": "John Doe",
      "changes": {
        "enabled": { "old": false, "new": true }
      },
      "createdAt": "2024-01-01T00:00:00Z"
    }
  ],
  "meta": { ... }
}

WebSocket Streaming

Connect

GET /stream
X-API-Key: hoist_live_xxx
Upgrade: websocket

Messages

Initial Config:

{
  "type": "config",
  "flags": [ ... ],
  "segments": [ ... ]
}

Flag Update:

{
  "type": "update",
  "keys": ["flag-key-1", "flag-key-2"]
}

Ping/Pong:

{ "type": "ping" }
{ "type": "pong" }

Health Check

GET /health

Response:

{
  "success": true,
  "data": {
    "status": "healthy",
    "postgres": "connected",
    "redis": "connected",
    "version": "1.0.0"
  }
}

Next Steps