MODULE 06 FULL DOCS

Building REST APIs for AI Consumption

Design APIs that AI agents can discover, understand, and use correctly without hallucinating endpoints or misinterpreting parameters. Transform your data layer into an AI-ready interface using DreamFactory's AI Data Gateway.

~20 min read
API Design
Best Practices Guide

🎯 Overview

Most REST APIs were designed for human developers who can read documentation, understand context, and make intelligent assumptions. AI agents don't have these luxuries. They need APIs that are self-explanatory, predictable, and bounded, or they'll hallucinate endpoints, misinterpret parameters, and return incorrect data.

This module teaches you how to design and implement REST APIs specifically optimized for AI consumption, using DreamFactory's auto-generated endpoints as the foundation.

What You'll Learn

  • Why traditional API design patterns fail with AI agents
  • The four core principles of AI-friendly API design
  • How DreamFactory auto-generates AI-optimized endpoints from your database
  • Query parameters that AI agents understand intuitively
  • Response structures that include the metadata AI needs
  • Real-world code reduction from custom APIs to DreamFactory

The Core Challenge

🤖

No Intuition

AI can't guess what /api/v2/res means or what parameters it accepts.

📚

Limited Context

AI can't read your internal docs or Slack conversations about API quirks.

💡

No Assumptions

AI won't assume status=1 means "active" unless explicitly told.

💥

Hallucination Risk

Ambiguous APIs lead AI to invent endpoints and parameters that don't exist.

⚠️ The AI API Problem

When AI agents interact with poorly designed APIs, several critical problems emerge. Understanding these failure modes is essential for designing APIs that work reliably with AI.

Problem 1: Hallucinated Endpoints

💥

The Hallucination Trap

When an AI agent encounters an API with unclear structure, it may "hallucinate" endpoints that seem logical but don't actually exist. The AI confidently calls /api/users/search when only /api/v2/users?filter=... exists.

What AI Tries

// AI hallucinates these endpoints
GET /api/users/search?q=john
GET /api/users/find-by-email
GET /api/users/active
GET /api/searchUsers
GET /api/user-lookup

What Actually Exists

// The real endpoint
GET /api/v2/db/_table/users

// With filtering
GET /api/v2/db/_table/users?filter=name%20like%20%27john%25%27

Problem 2: Misinterpreted Parameters

Traditional APIs often use abbreviated, inconsistent, or context-dependent parameter names. AI agents interpret these literally, leading to incorrect queries.

ParameterHuman UnderstandingAI InterpretationResult
st=1 "Status equals active" "st equals 1" (unknown meaning) AI may skip or misuse
dt_from "Filter by start date" "dt_from" (unclear field) Wrong date format used
inc=rel "Include related records" "inc equals rel" (cryptic) Relations not loaded
pg=2&lim=50 "Page 2, 50 per page" Possibly pagination? Inconsistent pagination

Problem 3: Unbounded Results

APIs without clear limits create context window problems for AI agents. When an endpoint returns 50,000 records, the AI either crashes, truncates important data, or enters an error loop.

⚠️

The Context Window Crisis

AI models have finite context windows (typically 8K-200K tokens). An unbounded API response can consume the entire context, leaving no room for the AI to process, reason about, or respond to the data. This often manifests as truncated responses, timeouts, or complete failures.

Problem 4: Missing Navigation

Without clear indicators of what actions are available, AI agents cannot explore your API systematically. They need explicit signals about relationships, available operations, and data boundaries.

📈 Traditional vs AI-Optimized APIs

The following comparison illustrates the fundamental differences between APIs designed for human developers and those optimized for AI consumption.

AspectTraditional APIAI-Optimized API
Endpoint Naming /api/v1/res, /getUsers /api/v2/db/_table/users
Parameter Style st, pg, lim status, offset, limit
Documentation External wiki, Confluence, PDFs OpenAPI spec, inline metadata
Result Limits None or server-configured Explicit limit parameter, max enforced
Response Format Data only: {"users": [...]} Data + metadata: count, schema, links
Relationships Separate endpoints, manual joins ?related=orders,addresses
Filtering Custom per-endpoint logic Consistent ?filter= syntax
Error Messages {"error": "Bad request"} Specific field errors with valid options
Schema Discovery Read the docs GET /_schema/{table}
Available Operations Trial and error OpenAPI spec lists all verbs
💡

The Key Insight

AI-optimized APIs trade brevity for clarity. What takes a human developer 2 seconds to decode (st=1) takes an AI model significant context and may still result in errors. Explicit naming (status=active) removes ambiguity entirely.

🎯 The Four Design Principles

AI-friendly API design follows four core principles. DreamFactory implements all four automatically when generating REST endpoints from your database schema.

📌
Descriptive Naming
Clear, unambiguous names
📄
Self-Describing
Metadata in responses
📏
Bounded Results
Explicit limits enforced
🔗
Clear Navigation
Discoverable structure

Principle 1 Descriptive Naming

Every endpoint, parameter, and field should be immediately understandable without external documentation. AI agents cannot look up what abbreviations mean, so the meaning must be in the name itself.

1

Use Full Words, Not Abbreviations

AvoidPreferReason
ststatus"st" could mean state, street, start time
usruserNo ambiguity about the resource
qtyquantityAI may not recognize abbreviation
dtdate or datetimeExplicit data type in name
amtamountClear numeric field indicator
2

Consistent Endpoint Patterns

DreamFactory generates endpoints following a predictable pattern that AI can learn and apply:

HTTP DreamFactory Endpoint Pattern
# Pattern: /api/v2/{service}/_table/{table_name}

# List all customers
GET  /api/v2/db/_table/customers

# Get specific customer by ID
GET  /api/v2/db/_table/customers/42

# Create new customer
POST /api/v2/db/_table/customers

# Update customer
PUT  /api/v2/db/_table/customers/42

# Delete customer
DELETE /api/v2/db/_table/customers/42

# The pattern is identical for every table
GET  /api/v2/db/_table/orders
GET  /api/v2/db/_table/products
GET  /api/v2/db/_table/invoices
💡

The Naming Test

If a new developer (or AI) cannot understand what an endpoint does from its URL alone, the name is not descriptive enough. /api/v2/db/_table/customer_orders tells you exactly what you'll get. /api/cust_ord does not.

Principle 2 Self-Describing Responses

Every API response should include metadata that tells the AI what it received, how much more data exists, and what the data structure looks like. This eliminates guesswork and reduces errors.

Traditional Response (Data Only)

Missing Context

{
  "users": [
    {"id": 1, "name": "John"},
    {"id": 2, "name": "Jane"}
  ]
}

// Questions AI cannot answer:
// - Is this all users or just a page?
// - How many total users exist?
// - What other fields are available?
// - Can I filter or sort this data?

AI-Optimized Response (DreamFactory Style)

Full Context Included

{
  "resource": [
    {
      "id": 1,
      "first_name": "John",
      "last_name": "Doe",
      "email": "[email protected]",
      "status": "active",
      "created_at": "2026-01-15T10:30:00Z"
    },
    {
      "id": 2,
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "[email protected]",
      "status": "active",
      "created_at": "2026-01-20T14:15:00Z"
    }
  ],
  "meta": {
    "count": 2,
    "total_count": 1547,
    "limit": 100,
    "offset": 0,
    "has_more": true
  }
}

What Metadata Provides

FieldPurposeHow AI Uses It
count Records in this response Knows how many items to process
total_count Total records matching query Determines if pagination needed
limit Max records per request Plans batch requests correctly
offset Current position in result set Calculates next page offset
has_more More results available Decides whether to continue fetching

Schema Discovery

DreamFactory also provides schema endpoints so AI can discover the structure of any table:

HTTP Schema Discovery Request
GET /api/v2/db/_schema/customers
JSON Schema Response
{
  "name": "customers",
  "label": "Customers",
  "field": [
    {
      "name": "id",
      "type": "integer",
      "is_primary_key": true,
      "auto_increment": true
    },
    {
      "name": "email",
      "type": "string",
      "length": 255,
      "is_unique": true,
      "validation": "email"
    },
    {
      "name": "status",
      "type": "string",
      "enum": ["active", "inactive", "pending"]
    },
    {
      "name": "created_at",
      "type": "datetime",
      "default": "CURRENT_TIMESTAMP"
    }
  ],
  "related": [
    {
      "name": "orders",
      "type": "has_many",
      "ref_table": "orders",
      "ref_field": "customer_id"
    }
  ]
}

Now the AI Knows Everything

With the schema response, an AI agent knows: what fields exist, their data types, which fields are required, valid values for enum fields, and how tables relate to each other. No documentation hunting required.

Principle 3 Bounded Results

Every query must return a predictable, bounded amount of data. AI agents have finite context windows, and unbounded queries cause truncation, timeouts, or complete failures.

💥

The Unbounded Query Disaster

Consider an AI agent that runs SELECT * FROM orders on a production database with 2 million records. The response consumes 500MB of memory, exceeds the context window, and crashes the AI workflow. Even if it doesn't crash, the AI cannot process or reason about millions of rows meaningfully.

DreamFactory Enforced Limits

DreamFactory provides multiple layers of protection against unbounded queries:

Protection LayerConfigurationEffect
Default Limit System-wide setting All queries return max N records unless specified
Max Limit Per-role setting Prevents ?limit=1000000 abuse
Request Timeout Per-service setting Long-running queries terminated
Response Size Server configuration Large responses rejected

Recommended Limit Strategy

HTTP AI-Friendly Query Pattern
# First query: Get count and sample
GET /api/v2/db/_table/orders?limit=10&include_count=true

# Response tells AI there are 15,000 total orders
# AI can then decide how to proceed:

# Option A: Filter to reduce scope
GET /api/v2/db/_table/orders?filter=status%3Dpending&limit=100

# Option B: Paginate through results
GET /api/v2/db/_table/orders?limit=100&offset=0
GET /api/v2/db/_table/orders?limit=100&offset=100
GET /api/v2/db/_table/orders?limit=100&offset=200

# Option C: Aggregate instead of retrieve all
GET /api/v2/db/_table/orders?group=status&fields=status,COUNT(*)%20as%20count
💡

The 100 Record Rule

For AI consumption, we recommend a default limit of 100 records. This provides enough data for meaningful analysis while staying well within context window limits. AI agents can always request more with explicit pagination.

Principle 4 Clear Navigation

AI agents need explicit signals about what data is available, how it relates to other data, and what operations they can perform. DreamFactory provides this through consistent patterns and relationship declarations.

Relationship Loading

Instead of making multiple queries, AI can request related data in a single call:

HTTP Related Data Request
# Get customer with their orders and addresses in one request
GET /api/v2/db/_table/customers/42?related=orders,addresses

# Get orders with customer info and line items
GET /api/v2/db/_table/orders?related=customer_by_customer_id,order_items&limit=50
JSON Response with Related Data
{
  "resource": [
    {
      "id": 42,
      "first_name": "John",
      "last_name": "Doe",
      "email": "[email protected]",
      "orders": [
        {
          "id": 1001,
          "order_date": "2026-01-15",
          "total": 299.99,
          "status": "shipped"
        },
        {
          "id": 1024,
          "order_date": "2026-02-01",
          "total": 149.50,
          "status": "pending"
        }
      ],
      "addresses": [
        {
          "id": 201,
          "type": "billing",
          "street": "123 Main St",
          "city": "Springfield",
          "state": "IL"
        }
      ]
    }
  ],
  "meta": {
    "count": 1
  }
}

Service Discovery

AI agents can discover all available tables and services:

HTTP Discovery Endpoints
# List all available services
GET /api/v2

# List all tables in a database service
GET /api/v2/db/_table

# Get schema for all tables
GET /api/v2/db/_schema

# Get stored procedures
GET /api/v2/db/_proc

DreamFactory Auto-Generated Endpoints

When you connect a database to DreamFactory, its AI Data Gateway automatically generates a complete REST API following all four AI-friendly principles. No code required.

DreamFactory 4-step database API creation wizard
DreamFactory's 4-step wizard generates a complete REST API from any supported database in minutes.

What Gets Generated

Database ObjectGenerated EndpointsOperations
Each Table /api/v2/{service}/_table/{name} GET, POST, PUT, PATCH, DELETE
Each View /api/v2/{service}/_table/{view} GET (read-only)
Stored Procedures /api/v2/{service}/_proc/{name} POST (execute)
Functions /api/v2/{service}/_func/{name} GET, POST
Schema /api/v2/{service}/_schema GET (discovery)

Generated OpenAPI Specification

DreamFactory also generates a complete OpenAPI (Swagger) specification that AI agents can use to understand the entire API:

HTTP OpenAPI Spec Endpoint
# Get the full OpenAPI spec for your API
GET /api/v2/api_docs

# Get OpenAPI spec for a specific service
GET /api/v2/db/api_docs

AI Agents Love OpenAPI

Many AI frameworks (including MCP servers and LangChain) can consume OpenAPI specifications directly. This means AI can discover all available endpoints, required parameters, expected response formats, and valid values without any custom integration work.

Endpoint Pattern Examples

HTTP Complete CRUD Operations
# ================================
# READ Operations
# ================================

# Get all records (with default limit)
GET /api/v2/db/_table/products

# Get single record by ID
GET /api/v2/db/_table/products/42

# Get multiple specific records
GET /api/v2/db/_table/products?ids=1,2,3,4,5

# Get with filtering
GET /api/v2/db/_table/products?filter=category%3Delectronics

# Get specific fields only
GET /api/v2/db/_table/products?fields=id,name,price

# Get with sorting
GET /api/v2/db/_table/products?order=price%20DESC

# Get with related data
GET /api/v2/db/_table/products?related=category_by_category_id,reviews

# ================================
# CREATE Operations
# ================================

# Create single record
POST /api/v2/db/_table/products
{
  "resource": [
    {"name": "New Product", "price": 29.99, "category_id": 5}
  ]
}

# Create multiple records (batch)
POST /api/v2/db/_table/products
{
  "resource": [
    {"name": "Product A", "price": 19.99},
    {"name": "Product B", "price": 39.99}
  ]
}

# ================================
# UPDATE Operations
# ================================

# Update single record
PUT /api/v2/db/_table/products/42
{
  "name": "Updated Name",
  "price": 34.99
}

# Partial update (PATCH)
PATCH /api/v2/db/_table/products/42
{
  "price": 29.99
}

# ================================
# DELETE Operations
# ================================

# Delete single record
DELETE /api/v2/db/_table/products/42

# Delete multiple records
DELETE /api/v2/db/_table/products?ids=1,2,3

🔍 Query Parameters AI Understands

DreamFactory uses intuitive, consistently-named query parameters that AI agents can understand without documentation. Here's the complete reference.

filter
Filter records using field comparisons. Supports complex conditions with AND/OR.
?filter=status=active AND created_at>2026-01-01
fields
Select specific fields to return. Reduces response size and improves performance.
?fields=id,name,email,created_at
related
Include related records from foreign key relationships.
?related=orders,addresses
order
Sort results by one or more fields. Supports ASC and DESC.
?order=created_at DESC,name ASC
limit
Maximum number of records to return. Essential for bounding results.
?limit=100
offset
Skip N records before returning results. Used for pagination.
?offset=200
include_count
Include total count of matching records in response metadata.
?include_count=true
group
Group results by specified fields. Used with aggregate functions.
?group=status&fields=status,COUNT(*)

Built-in Aggregation via MCP

When accessed through DreamFactory's MCP server, AI agents gain access to a dedicated {db}_aggregate_data tool that supports built-in aggregation functions without writing raw SQL:

FunctionDescriptionExample Use
SUMTotal of a numeric columnTotal revenue by region
COUNTNumber of matching recordsOrders per customer
AVGAverage of a numeric columnAverage order value
MINMinimum valueEarliest order date
MAXMaximum valueHighest sale amount

The aggregation tool supports GROUP BY and handles pagination internally for large datasets, so AI agents receive complete aggregated results without needing to manage multiple page requests.

💡

Aggregation vs. Raw Data

For analytical questions ("What is total revenue by region?"), the {db}_aggregate_data MCP tool is more efficient than fetching all records and summing in the AI context. It runs the aggregation in the database and returns a compact result.

Standard REST Query Parameters

All DreamFactory REST endpoints accept these standard query parameters: filter, order, limit, offset, fields, related, and include_count. These same parameters work consistently across tables, views, and MCP tool calls.

Filter Syntax Reference

The filter parameter supports a wide range of comparison operators:

OperatorDescriptionExample
= Equals filter=status=active
!= Not equals filter=status!=deleted
> Greater than filter=price>100
>= Greater than or equal filter=quantity>=10
< Less than filter=created_at<2026-01-01
<= Less than or equal filter=age<=65
like Pattern match (% wildcard) filter=name like John%
in In list of values filter=status in (active,pending)
is null Is null check filter=deleted_at is null
AND Combine conditions filter=status=active AND price>50
OR Alternative conditions filter=status=active OR status=pending
BETWEEN Range check (inclusive) filter=price BETWEEN 10 AND 100

Related Data & Limits

Use the related parameter to include foreign key data in a single request. The naming convention follows the pattern {parent_table}_by_{fk_field}:

HTTP Related Data & Limits
# Include related data via foreign key
?related=customer_by_customer_id

# MCP requests are capped at 1,000 records per call
# The platform default (DB_MAX_RECORDS_RETURNED) is 100,000
?limit=1000

Complex Query Example

HTTP AI-Generated Query
# AI prompt: "Show me the top 10 pending orders from January 2026
# with customer details, sorted by total amount"

GET /api/v2/db/_table/orders?
  filter=status%3Dpending%20AND%20order_date%3E%3D2026-01-01%20AND%20order_date%3C2026-02-01&
  related=customer_by_customer_id&
  fields=id,order_date,total,status,customer_by_customer_id.name,customer_by_customer_id.email&
  order=total%20DESC&
  limit=10&
  include_count=true

📄 AI-Friendly Response Structures

DreamFactory responses are structured to give AI agents maximum context with minimum ambiguity. Every response follows a consistent pattern.

Standard Response Structure

JSON Response Format
{
  // The actual data - always an array
  "resource": [
    { /* record 1 */ },
    { /* record 2 */ }
  ],

  // Metadata about the response (when include_count=true)
  "meta": {
    "count": 2,          // Records in this response
    "total_count": 547,  // Total matching records
    "limit": 100,        // Applied limit
    "offset": 0          // Applied offset
  }
}

Single Record Response

JSON GET /api/v2/db/_table/customers/42
{
  "id": 42,
  "first_name": "John",
  "last_name": "Doe",
  "email": "[email protected]",
  "status": "active",
  "created_at": "2026-01-15T10:30:00Z",
  "updated_at": "2026-02-01T14:22:00Z"
}

Error Response Structure

Errors include specific, actionable information that AI can use to correct its approach:

JSON Error Response
{
  "error": {
    "code": 400,
    "message": "Invalid filter syntax",
    "context": {
      "field": "filter",
      "value": "status == active",
      "hint": "Use single '=' for equality. Example: status=active"
    }
  }
}

// Another example: Invalid field name
{
  "error": {
    "code": 400,
    "message": "Field 'user_status' not found in table 'customers'",
    "context": {
      "table": "customers",
      "requested_field": "user_status",
      "available_fields": ["id", "name", "email", "status", "created_at"],
      "suggestion": "Did you mean 'status'?"
    }
  }
}

Self-Correcting AI

With detailed error messages that include available options, AI agents can self-correct. Instead of failing permanently, the AI learns from the error response and retries with the correct field name or syntax.

📈 The Code Reduction Story

One of the most compelling benefits of using DreamFactory for AI-friendly APIs is the dramatic reduction in custom code. Real enterprise deployments have seen transformational results.

140MB → 8KB
Enterprise .NET DLL Reduction
A Fortune 500 company replaced their custom data access layer with DreamFactory

The Traditional Approach

Building APIs the traditional way requires significant custom code for each endpoint:

C# Traditional API Controller (Simplified)
// Just ONE endpoint in a traditional API
// Multiply this by dozens of tables...

[ApiController]
[Route("api/[controller]")]
public class CustomersController : ControllerBase
{
    private readonly ICustomerRepository _repository;
    private readonly ILogger _logger;
    private readonly IMapper _mapper;
    private readonly IValidator _validator;

    [HttpGet]
    public async Task<ActionResult<PagedResult<CustomerDto>>> GetAll(
        [FromQuery] string filter,
        [FromQuery] string sort,
        [FromQuery] int page = 1,
        [FromQuery] int pageSize = 50)
    {
        // Parse filter expression
        var filterExpression = FilterParser.Parse(filter);

        // Validate filter fields
        var validationResult = _validator.ValidateFilter(filterExpression);
        if (!validationResult.IsValid)
            return BadRequest(validationResult.Errors);

        // Build query
        var query = _repository.Query()
            .ApplyFilter(filterExpression)
            .ApplySort(sort)
            .Skip((page - 1) * pageSize)
            .Take(pageSize);

        // Execute and map
        var results = await query.ToListAsync();
        var total = await _repository.CountAsync(filterExpression);
        var dtos = _mapper.Map<List<CustomerDto>>(results);

        // Return paged result
        return Ok(new PagedResult<CustomerDto>
        {
            Data = dtos,
            Page = page,
            PageSize = pageSize,
            TotalCount = total
        });
    }

    // ... hundreds more lines for POST, PUT, DELETE, related data, etc.
}

The DreamFactory Approach

With DreamFactory, you configure the connection and get all endpoints automatically:

JSON DreamFactory Service Configuration
{
  "name": "enterprise_db",
  "type": "sql_server",
  "config": {
    "host": "sql.company.com",
    "database": "production",
    "username": "${env.DB_USER}",
    "password": "${env.DB_PASS}"
  }
}

// That's it. DreamFactory now provides:
// - REST endpoints for ALL tables
// - Full CRUD operations
// - Filtering, sorting, pagination
// - Related data loading
// - Schema discovery
// - OpenAPI documentation
// - Role-based access control

Code Reduction Benefits

💻

Less Code to Maintain

No custom controllers, repositories, DTOs, or mappers for each table.

🚀

Faster Time-to-Market

New tables are instantly available as API endpoints. No development cycle.

🐛

Fewer Bugs

Battle-tested DreamFactory code vs. custom code with edge cases.

💰

Lower Costs

Less development time, less testing, less documentation to write.

💡

Keep Your Business Logic

DreamFactory doesn't replace your business logic; it replaces the boilerplate. Use stored procedures (Module 04) for complex operations that require business rules, and let DreamFactory handle the CRUD plumbing.

Best Practices

API Design Checklist

Before Deploying Your API for AI

  • Naming: All endpoints and fields use full, descriptive words (not abbreviations)
  • Documentation: OpenAPI spec is generated and accessible
  • Limits: Default and maximum limits are configured for all endpoints
  • Schema: Schema endpoints are enabled for AI discovery
  • Relationships: Foreign keys are defined so related parameter works
  • Errors: Error responses include actionable details and valid options
  • Testing: Tested with actual AI prompts to verify usability

Performance Tips

TipWhy It Matters for AI
Always use fields parameter Reduces response size, faster processing, less token usage
Set reasonable limit defaults Prevents context window overflow
Index columns used in filters AI queries often use the same patterns repeatedly
Use include_count strategically COUNT queries add overhead; only use when pagination needed
Cache schema responses Schema rarely changes; AI may query it frequently
DreamFactory API Keys bound to roles
API Keys are bound to roles, and each AI agent uses a unique key that enforces its specific access permissions.

Security Considerations

🔒

AI + API Security

AI agents can be manipulated through prompt injection. Always use role-based access control (Module 03) to limit what data an AI can access. Never give AI agents admin-level API access. Use the principle of least privilege.

  • Use identity passthrough (Module 05) so queries run as the user, not a service account
  • Define read-only roles for AI that only needs to query data
  • Exclude sensitive tables from AI-accessible services
  • Enable audit logging to track AI-initiated queries
  • Set rate limits to prevent AI loops from overwhelming the API

🔧 Troubleshooting

AI Hallucinates Non-Existent Endpoints

Symptom: AI tries to call /api/users/search or /api/findUserByEmail

Cause: AI is guessing endpoint patterns based on common conventions

Fix: Provide the OpenAPI spec to the AI context. This gives it the exact endpoint list. In MCP configurations, set the API spec URL so the AI can discover real endpoints.

Context Window Overflow

Symptom: AI responses are truncated or the AI crashes/times out

Cause: Query returned too many records, exceeding context limits

Fix: Enforce lower limits. Set system-wide default limit to 100. For large tables, require filters. Use include_count=true so AI knows the scope before fetching all data.

AI Uses Wrong Filter Syntax

Symptom: AI constructs filters like status == 'active' or WHERE status = 'active'

Cause: AI is using SQL or programming language syntax instead of DreamFactory syntax

Fix: Include filter syntax examples in AI context. The error response should include the correct syntax. Example: filter=status=active (single equals, no quotes for simple values).

Related Data Not Loading

Symptom: AI requests ?related=orders but response doesn't include orders

Cause: Foreign key relationship not defined or wrong relationship name

Fix: Check schema endpoint for correct relationship names. DreamFactory names relationships as {table}_by_{foreign_key}. Use schema discovery: GET /api/v2/db/_schema/customers to see exact names.

Slow Queries from AI

Symptom: AI-generated queries take 10+ seconds to return

Cause: Missing indexes on filtered columns, or unoptimized AI query patterns

Fix: Monitor which filters AI uses most. Add database indexes for commonly filtered columns. Consider creating database views for complex AI query patterns.

Debugging AI API Interactions

HTTP Useful Debug Endpoints
# Check what tables are available
GET /api/v2/db/_table

# Check schema for a specific table
GET /api/v2/db/_schema/customers

# Check available relationships
GET /api/v2/db/_schema/customers?related=true

# Test filter syntax with minimal data
GET /api/v2/db/_table/customers?filter=id=1&fields=id

# Get OpenAPI spec for reference
GET /api/v2/db/api_docs