API Reference

FLXBL automatically generates REST and GraphQL APIs from your schema. This reference covers all available endpoints and operations.

Base URL

All API requests use this base URL:

https://api.flxbl.dev/api/v1

For self-hosted instances, use your configured URL.

Authentication

Use API keys for programmatic access to the FLXBL Dynamic API. Include your API key in the Authorization header:

# API Key Authentication
curl -X GET https://api.flxbl.dev/api/v1/dynamic/Product \
  -H "Authorization: Bearer flxbl_ab12cd34_..."

# Get your API key from your FLXBL dashboard at platform.flxbl.dev

Generate API keys from your FLXBL dashboard at platform.flxbl.dev. API keys are scoped to your tenant and provide access to the Dynamic API endpoints.

REST API Endpoints

For each entity in your schema, these endpoints are generated:

# Entity CRUD Operations
GET    /api/v1/dynamic/{Entity}           # List all
POST   /api/v1/dynamic/{Entity}           # Create
GET    /api/v1/dynamic/{Entity}/:id       # Read
PUT    /api/v1/dynamic/{Entity}/:id       # Full update
PATCH  /api/v1/dynamic/{Entity}/:id       # Partial update
DELETE /api/v1/dynamic/{Entity}/:id       # Delete
POST   /api/v1/dynamic/{Entity}/query     # Query with DSL

# Relationship Operations
POST   /api/v1/dynamic/{Entity}/:id/relationships/{rel}
GET    /api/v1/dynamic/{Entity}/:id/relationships/{rel}?direction=out
PATCH  /api/v1/dynamic/{Entity}/:id/relationships/{rel}/:targetId
DELETE /api/v1/dynamic/{Entity}/:id/relationships/{rel}/:targetId

# GraphQL Endpoint
POST   /api/v1/dynamic-gql/:tenantId
GET    /api/v1/dynamic-gql/:tenantId/schema.graphql
Important: Entity names in URLs are case-sensitive. Use the exact name from your schema (e.g., Product not products).

Create (POST)

# Create a product
curl -X POST https://api.flxbl.dev/api/v1/dynamic/Product \
  -H "Authorization: Bearer flxbl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Wireless Headphones",
    "price": 299.99,
    "inStock": true,
    "tags": ["electronics", "audio"]
  }'

# Response
{
  "id": "node_abc123",
  "name": "Wireless Headphones",
  "price": 299.99,
  "inStock": true,
  "tags": ["electronics", "audio"],
  "createdAt": "2025-01-15T10:30:00Z",
  "updatedAt": "2025-01-15T10:30:00Z"
}

Read (GET)

# Get a product by ID
curl -X GET https://api.flxbl.dev/api/v1/dynamic/Product/node_abc123 \
  -H "Authorization: Bearer flxbl_your_api_key"

# List all products
curl -X GET https://api.flxbl.dev/api/v1/dynamic/Product \
  -H "Authorization: Bearer flxbl_your_api_key"

Update (PUT/PATCH)

# Full update (PUT) - replaces all fields
curl -X PUT https://api.flxbl.dev/api/v1/dynamic/Product/node_abc123 \
  -H "Authorization: Bearer flxbl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Premium Wireless Headphones",
    "price": 349.99,
    "inStock": true,
    "tags": ["electronics", "audio", "premium"]
  }'

# Partial update (PATCH) - only updates specified fields
curl -X PATCH https://api.flxbl.dev/api/v1/dynamic/Product/node_abc123 \
  -H "Authorization: Bearer flxbl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "price": 279.99
  }'

Delete (DELETE)

# Delete a product
# IMPORTANT: Do NOT include Content-Type header for DELETE without body
curl -X DELETE https://api.flxbl.dev/api/v1/dynamic/Product/node_abc123 \
  -H "Authorization: Bearer flxbl_your_api_key"
Important: Do NOT include Content-Type: application/json header for DELETE requests without a body. This will cause a 400 error.

Relationship Operations

Manage relationships between entities:

# Create a relationship
curl -X POST https://api.flxbl.dev/api/v1/dynamic/Product/node_abc/relationships/BELONGS_TO \
  -H "Authorization: Bearer flxbl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "targetId": "node_category_xyz",
    "properties": {
      "addedAt": "2025-01-15T10:30:00Z"
    }
  }'

# Get relationships
curl -X GET "https://api.flxbl.dev/api/v1/dynamic/Product/node_abc/relationships/BELONGS_TO?direction=out" \
  -H "Authorization: Bearer flxbl_your_api_key"

# Delete a relationship
curl -X DELETE https://api.flxbl.dev/api/v1/dynamic/Product/node_abc/relationships/BELONGS_TO/node_category_xyz \
  -H "Authorization: Bearer flxbl_your_api_key"

Batch Operations

FLXBL supports batch operations for high-performance bulk data processing. All batch operations are atomic (all-or-nothing) and support up to 1,000 items per request.

Batch Create (POST)

Create multiple entities in a single request:

# Batch create multiple products
curl -X POST https://api.flxbl.dev/api/v1/dynamic/Product/batch \
  -H "Authorization: Bearer flxbl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "name": "Widget A", "price": 29.99 },
      { "name": "Widget B", "price": 39.99 }
    ]
  }'

# Response
{
  "successful": [
    { "id": "node_abc", "name": "Widget A", "price": 29.99, ... },
    { "id": "node_def", "name": "Widget B", "price": 39.99, ... }
  ],
  "failed": [],
  "totalCount": 2,
  "successCount": 2,
  "failureCount": 0,
  "stats": {
    "processingTimeMs": 150,
    "validationTimeMs": 20,
    "databaseTimeMs": 130
  }
}

Batch Update (PATCH)

Update multiple entities at once. Each item requires an id and a data object:

# Batch update multiple products
curl -X PATCH https://api.flxbl.dev/api/v1/dynamic/Product/batch \
  -H "Authorization: Bearer flxbl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "id": "node_abc", "data": { "price": 24.99 } },
      { "id": "node_def", "data": { "price": 34.99 } }
    ]
  }'

Batch Delete (DELETE)

Delete multiple entities by their IDs:

# Batch delete multiple products
curl -X DELETE https://api.flxbl.dev/api/v1/dynamic/Product/batch \
  -H "Authorization: Bearer flxbl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "ids": ["node_abc", "node_def", "node_ghi"]
  }'

Response Format

All batch operations return a consistent response format with success/failure details and performance metrics:

# Response format (all batch operations)
{
  "successful": [ ... ],     # Successfully processed entities
  "failed": [                # Failed items with error details
    {
      "index": 1,
      "item": { "name": "Invalid" },
      "error": {
        "code": "VALIDATION_ERROR",
        "message": "Field 'price' is required",
        "field": "price"
      }
    }
  ],
  "totalCount": 10,          # Total items in request
  "successCount": 9,         # Successfully processed
  "failureCount": 1,         # Failed items
  "stats": {                 # Performance metrics
    "processingTimeMs": 150,
    "validationTimeMs": 20,
    "databaseTimeMs": 130
  }
}
Field Description
successful Array of successfully processed entities
failed Array of failed items with index and error details
successCount Number of successfully processed items
failureCount Number of failed items
stats Performance metrics (processing, validation, database time)
Note: Batch operations are pre-validated before any database writes. If validation fails for any item, the entire batch is rejected.

GraphQL API

FLXBL also generates a complete GraphQL API. The endpoint requires your tenant ID:

# GraphQL endpoint
POST /api/v1/dynamic-gql/:tenantId

# Query example
query {
  products(where: { inStock: { equals: true } }, limit: 10) {
    id
    name
    price
    belongsTo {
      id
      name
    }
  }
}

# Count query - get total count for pagination
query {
  productsCount(where: { inStock: { equals: true } })
}
# Returns: { "data": { "productsCount": 157 } }

# Query with sorting
query {
  products(
    where: { inStock: { equals: true } }
    orderBy: "price"
    orderDirection: ASC
    limit: 20
    offset: 0
  ) {
    id
    name
    price
  }
}

# Mutation example
mutation {
  createProduct(input: {
    name: "New Product"
    price: 99.99
  }) {
    id
    name
    createdAt
  }
}

Download the GraphQL schema:

GET /api/v1/dynamic-gql/{tenantId}/schema.graphql

Cursor-Based Pagination

FLXBL implements the Relay Connection specification for cursor-based pagination, providing stable, efficient pagination even when data changes.

# GraphQL cursor pagination (Relay spec)
query {
  productsConnection(first: 10) {
    edges {
      cursor
      node {
        id
        name
        price
      }
    }
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
    totalCount
  }
}

# Next page using cursor
query {
  productsConnection(first: 10, after: "eyJpZCI6Im5vZGVfMTAifQ==") {
    edges {
      cursor
      node { id name }
    }
    pageInfo { hasNextPage endCursor }
  }
}

# Backward pagination
query {
  productsConnection(last: 10, before: "eyJpZCI6Im5vZGVfMjAifQ==") {
    edges { cursor node { id name } }
    pageInfo { hasPreviousPage startCursor }
  }
}

Pagination arguments:

Argument Description
first Number of items to fetch (forward pagination, max 100)
after Cursor to start after (use endCursor from previous page)
last Number of items to fetch (backward pagination, max 100)
before Cursor to start before (use startCursor from previous page)
Important: You cannot use first and last together. Use first/after for forward pagination or last/before for backward pagination.

GraphQL Batch Mutations

GraphQL also supports batch mutations for bulk operations with the same semantics as REST batch endpoints:

# Batch create mutation
mutation {
  batchCreateProduct(input: [
    { name: "Widget A", price: 29.99 },
    { name: "Widget B", price: 39.99 }
  ]) {
    successful { id name price }
    failed { index error { code message field } }
    successCount
    failureCount
  }
}

# Batch update mutation
mutation {
  batchUpdateProduct(input: [
    { id: "node_abc", data: { price: 24.99 } },
    { id: "node_def", data: { price: 34.99 } }
  ]) {
    successful { id name price }
    successCount
  }
}

# Batch delete mutation
mutation {
  batchDeleteProduct(ids: ["node_abc", "node_def"]) {
    successful { id }
    successCount
    failureCount
  }
}

Available batch mutations for each entity:

  • batchCreate{Entity} - Create multiple entities
  • batchUpdate{Entity} - Update multiple entities by ID
  • batchDelete{Entity} - Delete multiple entities by ID

Integrate with External Tools

FLXBL generates standard OpenAPI and GraphQL specifications that work with your favorite API tools.

Postman / Insomnia

Import your schema's OpenAPI spec directly into Postman or Insomnia for interactive API testing:

  1. Download your OpenAPI spec: GET /api/v1/schemas/:schemaId/openapi.json
  2. In Postman: Import → File → Select openapi.json
  3. All your entity endpoints, authentication, and request bodies are ready to use

Apollo Sandbox / GraphiQL

Connect Apollo Sandbox or GraphiQL to your GraphQL endpoint for schema exploration and query building:

  1. Point your GraphQL client to POST /api/v1/dynamic-gql/:tenantId
  2. Include your API key in the Authorization: Bearer flxbl_xxx header
  3. Download the schema: GET /api/v1/dynamic-gql/:tenantId/schema.graphql
Tip: The GraphQL endpoint supports introspection, so tools like Apollo Sandbox will automatically discover your schema's types and operations.

Rate Limiting

FLXBL implements multi-layer rate limiting:

Layer Default Limit Scope
Global 500 req/min Per IP address
Auth endpoints 20 req/min Per IP address
Tenant 300 req/min Per tenant

Rate limit information is included in response headers:

# Rate limit headers in response
X-RateLimit-Limit: 100          # Max requests per window
X-RateLimit-Remaining: 95       # Requests remaining
X-RateLimit-Reset: 60           # Seconds until reset

When rate limited, the API returns 429 Too Many Requests. Use the X-RateLimit-Reset header to know when to retry.

Error Responses

Errors follow a consistent format:

Status Meaning
400 Bad request - Invalid input or missing required fields
401 Unauthorized - Missing or invalid authentication
403 Forbidden - Insufficient permissions
404 Not found - Entity or resource doesn't exist
429 Too many requests - Rate limit exceeded
500 Internal error - Server-side issue

Next Steps