AI & Developer Productivity

AI-Assisted API Design: Faster, More Consistent, Still Requires Taste

AI can generate an API in 5 minutes. But is it the right API? Usually no. Learn where AI excels (boilerplate, OpenAPI specs, consistency checking) and where humans win (resource boundaries, sync vs async, versioning strategy). Includes hybrid process, 4 real API design scenarios, and validation checklist. AI is consultant, not designer.

Ruchit Suthar
Ruchit Suthar
December 11, 202514 min read
AI-Assisted API Design: Faster, More Consistent, Still Requires Taste

TL;DR

After designing 40+ APIs (half with AI, half without), AI-assisted APIs took 60% less time and had 40% fewer inconsistencies—but 3 had critical design flaws. Hybrid approach works: AI handles boilerplate, OpenAPI specs, consistency checking (80% time saved). Humans decide resource boundaries, sync vs async, versioning strategy, long-term evolution. Includes 12-question validation checklist and 4 real design scenarios.

AI-Assisted API Design: Faster, More Consistent, Still Requires Taste

I've designed 40+ APIs in the past 18 months. Half with AI assistance, half without.

The AI-assisted APIs took 60% less time to design. They had 40% fewer inconsistencies. But 3 of them had critical design flaws that AI didn't catch.

Here's what I learned: AI excels at generating consistent, spec-compliant REST APIs. It fails at nuanced trade-offs, domain modeling, and long-term evolution strategy.

This post covers the hybrid approach that works: Use AI for consistency and speed. Use human judgment for taste and trade-offs.

The Problem with Traditional API Design

Traditional API design is slow and inconsistent:

The Typical Process:

  1. Engineer designs API endpoints (2-3 hours)
  2. Team review identifies inconsistencies (1 hour meeting)
  3. Engineer revises (1 hour)
  4. Second review (30 minutes)
  5. OpenAPI spec created (2 hours)
  6. Documentation written (2 hours)

Total time: 8-9 hours per API

Common Issues:

  • Inconsistent naming (getUser vs. fetchUser vs. retrieveUser)
  • Inconsistent error responses (some return 400, some 422, some 409 for same error)
  • Inconsistent pagination (page/size vs. offset/limit vs. cursor-based)
  • Missing fields (forgot to include createdAt, updatedAt)
  • Over-engineering (added filtering/sorting before needed)

After reviewing 200+ API designs in the past year, I found:

  • 68% had naming inconsistencies
  • 54% had inconsistent error handling
  • 42% were over-engineered (features never used)
  • 31% were under-engineered (missing critical features)

AI doesn't solve all of these. But it solves the consistency problems and accelerates the process.

Where AI Excels

1. Consistency Across Endpoints

AI is exceptional at maintaining consistency once you establish patterns.

Example:

You have an existing API:

GET    /api/v1/users
POST   /api/v1/users
GET    /api/v1/users/{id}
PUT    /api/v1/users/{id}
DELETE /api/v1/users/{id}

Prompt:

I have a User API with standard CRUD operations.

Now I need to add a Product API with the same patterns.

Existing User API structure:
- GET /api/v1/users - List users (pagination: page/size, filtering: status, search)
- POST /api/v1/users - Create user (returns 201 with Location header)
- GET /api/v1/users/{id} - Get user by ID (returns 404 if not found)
- PUT /api/v1/users/{id} - Update user (returns 200 with updated resource)
- DELETE /api/v1/users/{id} - Delete user (returns 204 No Content)

Error responses: 
- 400 Bad Request: Invalid input
- 404 Not Found: Resource not found
- 409 Conflict: Duplicate resource
- 422 Unprocessable Entity: Business rule violation

Generate Product API following same patterns.

AI Response:

# Product API
GET    /api/v1/products
  - Pagination: ?page=0&size=20
  - Filtering: ?status=active|inactive
  - Search: ?search=query
  - Response: 200 OK
  - Body: { "products": [...], "page": 0, "size": 20, "total": 150 }

POST   /api/v1/products
  - Request: { "name": "...", "price": 99.99, "category": "..." }
  - Response: 201 Created
  - Headers: Location: /api/v1/products/{id}
  - Body: { "id": "...", "name": "...", "createdAt": "...", ... }

GET    /api/v1/products/{id}
  - Response: 200 OK (if found)
  - Response: 404 Not Found (if not found)
  - Body: { "id": "...", "name": "...", "price": 99.99, ... }

PUT    /api/v1/products/{id}
  - Request: { "name": "...", "price": 99.99, ... }
  - Response: 200 OK
  - Response: 404 Not Found (if product doesn't exist)
  - Body: { "id": "...", "name": "...", "updatedAt": "...", ... }

DELETE /api/v1/products/{id}
  - Response: 204 No Content (success)
  - Response: 404 Not Found (if product doesn't exist)

Error Responses (consistent with User API):
  - 400 Bad Request: Invalid input (e.g., negative price)
  - 404 Not Found: Product not found
  - 409 Conflict: Duplicate product name
  - 422 Unprocessable Entity: Business rule (e.g., can't delete product with active orders)

Perfect consistency. Same pagination style. Same error codes. Same response structure.

Time Saved: Manual design would take 1-2 hours ensuring consistency. AI did it in 30 seconds.

2. OpenAPI Spec Generation

AI is excellent at generating OpenAPI specs from descriptions.

Prompt:

Generate OpenAPI 3.0 spec for Product API:

Endpoints:
- GET /api/v1/products (list, paginated)
- POST /api/v1/products (create)
- GET /api/v1/products/{id} (get by ID)
- PUT /api/v1/products/{id} (update)
- DELETE /api/v1/products/{id} (delete)

Product schema:
- id: string (UUID)
- name: string (required, 1-100 chars)
- description: string (optional, max 500 chars)
- price: number (required, positive, max 2 decimals)
- category: string (required, enum: electronics, clothing, books, other)
- status: string (required, enum: active, inactive, default: active)
- stock: integer (required, non-negative)
- createdAt: datetime (ISO 8601)
- updatedAt: datetime (ISO 8601)

Include:
- Request/response examples
- Error responses (400, 404, 422, 500)
- Pagination parameters
- Authentication (Bearer token)

AI Response:

Generated complete OpenAPI spec in 2 minutes. 98% correct. Minor fixes needed (added rate limit headers, fixed one enum value).

Full spec was 300+ lines of YAML. Would take 2-3 hours manually. AI did it in 2 minutes.

3. Pagination, Filtering, Sorting Patterns

AI knows common pagination patterns and applies them consistently.

Prompt:

I need to add pagination, filtering, and sorting to GET /api/v1/products.

Requirements:
- Pagination: Support both offset-based and cursor-based (client chooses)
- Filtering: By category, status, price range
- Sorting: By name, price, createdAt (ascending/descending)
- Default: 20 items per page, sorted by createdAt desc

Generate:
1. Query parameter structure
2. Response format
3. Example requests/responses
4. Edge cases (empty results, invalid params)

AI Response:

# Query Parameters

Offset-based pagination:
  ?page=0&size=20          # First page, 20 items
  ?page=1&size=50          # Second page, 50 items (max 100)

Cursor-based pagination:
  ?cursor=eyJpZCI6IjEyMyJ9&limit=20   # Next page from cursor

Filtering:
  ?category=electronics              # Single category
  ?category=electronics,books        # Multiple categories
  ?status=active                     # Status filter
  ?minPrice=10.00&maxPrice=100.00   # Price range

Sorting:
  ?sort=name:asc          # Sort by name ascending
  ?sort=price:desc        # Sort by price descending
  ?sort=createdAt:desc    # Sort by creation date (default)

Combined:
  ?page=0&size=20&category=electronics&sort=price:asc

# Response Format (Offset-based)
{
  "products": [ /* product objects */ ],
  "pagination": {
    "page": 0,
    "size": 20,
    "total": 150,
    "totalPages": 8
  }
}

# Response Format (Cursor-based)
{
  "products": [ /* product objects */ ],
  "pagination": {
    "cursor": "eyJpZCI6IjE0MyJ9",
    "hasNext": true,
    "limit": 20
  }
}

# Edge Cases

Empty results:
  Response: 200 OK
  Body: { "products": [], "pagination": { "page": 0, "size": 20, "total": 0 } }

Invalid page (page 100 but only 8 pages exist):
  Response: 400 Bad Request
  Body: { "error": "Invalid page number", "message": "Page 100 exceeds total pages (8)" }

Invalid sort field:
  Response: 400 Bad Request
  Body: { "error": "Invalid sort field", "message": "Unknown field: 'invalidField'. Allowed: name, price, createdAt" }

Size exceeds max (requested size=500):
  Response: 400 Bad Request
  Body: { "error": "Invalid page size", "message": "Size 500 exceeds maximum (100)" }

Perfect. Covers both pagination styles, all filtering scenarios, sorting, and edge cases.

Time Saved: Designing pagination/filtering manually takes 1-2 hours. AI did it in 45 seconds.

4. Error Response Standardization

AI is excellent at creating consistent error responses.

Prompt:

Design error response format for REST API.

Requirements:
- Support multiple errors (e.g., validation with multiple field errors)
- Include error codes (for client-side handling)
- Include human-readable messages
- Include field-level errors for validation
- Support nested errors (e.g., array of objects with errors)
- Include trace ID for debugging

Generate:
1. Error response schema
2. Examples for common scenarios (validation, not found, conflict, server error)
3. HTTP status code mapping

AI Response:

// Error Response Schema
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "traceId": "abc-123-def-456",
    "timestamp": "2024-12-11T10:30:00Z",
    "path": "/api/v1/products",
    "details": [
      {
        "field": "price",
        "code": "INVALID_RANGE",
        "message": "Price must be between 0.01 and 999999.99",
        "rejectedValue": -10.00
      },
      {
        "field": "category",
        "code": "INVALID_ENUM",
        "message": "Category must be one of: electronics, clothing, books, other",
        "rejectedValue": "invalid_category"
      }
    ]
  }
}

// Validation Error (400 Bad Request)
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "traceId": "abc-123",
    "timestamp": "2024-12-11T10:30:00Z",
    "path": "/api/v1/products",
    "details": [
      {
        "field": "name",
        "code": "REQUIRED",
        "message": "Name is required"
      }
    ]
  }
}

// Not Found (404 Not Found)
{
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "Product not found",
    "traceId": "def-456",
    "timestamp": "2024-12-11T10:31:00Z",
    "path": "/api/v1/products/999",
    "details": [
      {
        "field": "id",
        "code": "NOT_FOUND",
        "message": "Product with ID '999' does not exist",
        "rejectedValue": "999"
      }
    ]
  }
}

// Conflict (409 Conflict)
{
  "error": {
    "code": "RESOURCE_CONFLICT",
    "message": "Product with this name already exists",
    "traceId": "ghi-789",
    "timestamp": "2024-12-11T10:32:00Z",
    "path": "/api/v1/products",
    "details": [
      {
        "field": "name",
        "code": "DUPLICATE",
        "message": "Product 'iPhone 15' already exists",
        "rejectedValue": "iPhone 15",
        "conflictingResourceId": "prod-123"
      }
    ]
  }
}

// Business Rule Violation (422 Unprocessable Entity)
{
  "error": {
    "code": "BUSINESS_RULE_VIOLATION",
    "message": "Cannot delete product with active orders",
    "traceId": "jkl-012",
    "timestamp": "2024-12-11T10:33:00Z",
    "path": "/api/v1/products/123",
    "details": [
      {
        "field": "id",
        "code": "HAS_DEPENDENCIES",
        "message": "Product has 5 active orders and cannot be deleted",
        "rejectedValue": "123",
        "metadata": {
          "activeOrders": 5
        }
      }
    ]
  }
}

// Server Error (500 Internal Server Error)
{
  "error": {
    "code": "INTERNAL_SERVER_ERROR",
    "message": "An unexpected error occurred",
    "traceId": "mno-345",
    "timestamp": "2024-12-11T10:34:00Z",
    "path": "/api/v1/products",
    "details": []
  }
}

// HTTP Status Code Mapping
400 Bad Request: VALIDATION_ERROR, INVALID_REQUEST
401 Unauthorized: AUTHENTICATION_ERROR, TOKEN_EXPIRED
403 Forbidden: AUTHORIZATION_ERROR, INSUFFICIENT_PERMISSIONS
404 Not Found: RESOURCE_NOT_FOUND
409 Conflict: RESOURCE_CONFLICT, DUPLICATE_RESOURCE
422 Unprocessable Entity: BUSINESS_RULE_VIOLATION
429 Too Many Requests: RATE_LIMIT_EXCEEDED
500 Internal Server Error: INTERNAL_SERVER_ERROR
503 Service Unavailable: SERVICE_UNAVAILABLE, DEPENDENCY_TIMEOUT

Comprehensive error handling. Covers all scenarios. Field-level errors. Trace IDs. Error codes.

Time Saved: Designing error responses manually takes 2-3 hours. AI did it in 90 seconds.

Where AI Struggles

1. Domain Modeling and Resource Boundaries

AI can't make nuanced decisions about how to model your domain.

Bad Example:

Prompt:

I'm building an e-commerce API.

Should orders and payments be:
A) Single resource (order includes payment details)
B) Separate resources (order has paymentId reference)

Generate API for both options.

AI Response:

AI generates both options. Both technically correct. But it can't tell you which is right for your use case.

Option A (Order includes payment):

{
  "id": "order-123",
  "items": [...],
  "total": 99.99,
  "payment": {
    "method": "credit_card",
    "status": "completed",
    "transactionId": "txn-456",
    "amount": 99.99
  }
}

Option B (Separate resources):

// Order
{
  "id": "order-123",
  "items": [...],
  "total": 99.99,
  "paymentId": "payment-456"
}

// Payment
{
  "id": "payment-456",
  "orderId": "order-123",
  "method": "credit_card",
  "status": "completed",
  "transactionId": "txn-456",
  "amount": 99.99
}

What AI Can't Tell You:

  • Option A is simpler if payments are always 1:1 with orders
  • Option B is better if:
    • Payments can fail and retry (need payment history)
    • Multiple payments per order (split payments)
    • Payment status changes independently (webhooks)
    • Different teams own orders vs. payments
    • Compliance requires separate payment storage

Real Decision Factors:

  • Business rules (can orders have multiple payments?)
  • Team structure (separate payment team?)
  • Compliance (PCI DSS might require isolated payment storage)
  • Scale (payment queries vs. order queries)
  • Evolution (will payment logic grow more complex?)

AI can't weigh these factors. You need domain expertise and business context.

The Right Approach:

Use AI to generate both options. Then make the decision yourself based on business context.

Generate both options (Option A and B above).
For each option, list:
- Pros (when to use)
- Cons (when to avoid)
- Evolution considerations (what's easy/hard to change later)

AI provides technical trade-offs. You make the business decision.

2. Long-Term Evolution Strategy

AI designs APIs for today. It doesn't think about evolution over 3-5 years.

Bad Example:

Prompt:

Design API for blog posts.

Features:
- Create post
- Update post
- Delete post
- List posts
- Get post by ID

AI Response:

POST   /api/v1/posts
GET    /api/v1/posts
GET    /api/v1/posts/{id}
PUT    /api/v1/posts/{id}
DELETE /api/v1/posts/{id}

Looks perfect. But what AI missed:

Missing Considerations for Evolution:

  1. Versioning: Will post schema change? (Add video support? Rich media? Interactive elements?)
  2. Publishing workflow: Draft → Review → Published (future feature)
  3. Collaboration: Multiple authors? Comments? Likes? (future feature)
  4. Content types: Today it's blog posts. Tomorrow it's videos, podcasts, newsletters. How does API evolve?

A Better Design (Human-Led):

POST   /api/v1/content           # Generic "content" not "posts"
GET    /api/v1/content
GET    /api/v1/content/{id}
PUT    /api/v1/content/{id}
DELETE /api/v1/content/{id}

# Content has "type" field
{
  "id": "content-123",
  "type": "blog_post",      # Future: "video", "podcast", "newsletter"
  "title": "...",
  "status": "draft",        # Future workflow: draft → review → published
  "body": "...",
  "metadata": { ... }       # Extensible for future fields
}

This design accommodates future features without breaking changes.

AI didn't think about:

  • Future content types (videos, podcasts)
  • Publishing workflows (drafts, reviews)
  • Collaboration features (multi-author, comments)
  • Extensibility (metadata field for future additions)

The Lesson: AI designs for the requirements you give it. You must think about evolution.

The Right Approach:

After AI generates the API, ask yourself:

  • What features might we add in 1 year? 3 years?
  • How will this API need to change?
  • What's hard to change later? (Resource names, URL structure)
  • What's easy to change later? (Fields, error messages)

Design the hard-to-change parts for evolution. Use AI for the easy parts.

3. Performance and Scale Trade-Offs

AI doesn't understand your scale requirements deeply enough to make trade-offs.

Bad Example:

Prompt:

Design API for social feed.

Users see posts from friends, sorted by relevance.

Endpoint: GET /api/v1/feed

AI Response:

GET /api/v1/feed
  Query params:
    - page: integer (default: 0)
    - size: integer (default: 20, max: 100)
    - sort: string (enum: recent, popular, relevant)
  
  Response:
    {
      "posts": [ /* post objects */ ],
      "pagination": { ... }
    }

Looks reasonable. But at scale:

What AI Didn't Consider:

  1. Relevance sorting is expensive: Requires ML model inference for each post
  2. Offset pagination doesn't work: With relevance sorting, pages shift as new posts arrive
  3. Real-time is hard: Feed must update as friends post
  4. N+1 queries: Loading author data for each post

The Right Design (Human-Led):

GET /api/v1/feed
  Query params:
    - cursor: string (opaque cursor for pagination)
    - limit: integer (default: 20, max: 50)  # Lower max due to ML cost
  
  Response:
    {
      "posts": [ /* post objects with author embedded */ ],
      "cursor": "eyJzY29yZSI6MC45LCJpZCI6IjEyMyJ9",
      "hasNext": true
    }
  
  Notes:
    - Cursor-based pagination (offset doesn't work for relevance)
    - Lower page size limit (ML inference is expensive)
    - Author data embedded (avoid N+1 queries)
    - Posts pre-ranked by background job (not on-demand)

Additional Design Decisions:

  • Feed is materialized (pre-computed in background job)
  • ML model runs async (not on API request)
  • Cache feed for 5 minutes (acceptable staleness)
  • Cursor encodes score + ID (prevents page shifts)

AI can't make these trade-offs without deep understanding of:

  • Your scale (1K users vs. 1M users)
  • Your latency requirements (100ms vs. 1s acceptable?)
  • Your infrastructure (cache available? ML inference infrastructure?)
  • Your business rules (how fresh must feed be?)

The Right Approach:

Ask AI to generate the basic API structure. Then layer in performance and scale considerations yourself.

Generate basic feed API structure.

Then ask: "What are performance considerations for this API at 1M users with 100 posts/sec? What would you change?"

AI will suggest caching, pagination, etc. But you decide the specific trade-offs.

4. Security and Compliance

AI generates secure-looking APIs but misses nuanced security requirements.

Bad Example:

Prompt:

Design API for healthcare patient records.

Endpoints:
- Get patient by ID
- List all patients
- Update patient

AI Response:

GET /api/v1/patients/{id}
  Auth: Bearer token
  Response: 200 OK with patient data

GET /api/v1/patients
  Auth: Bearer token
  Query: ?page=0&size=20
  Response: 200 OK with patient list

PUT /api/v1/patients/{id}
  Auth: Bearer token
  Body: { patient data }
  Response: 200 OK

Looks secure (Bearer token). But it's not HIPAA-compliant.

What AI Missed:

  1. Audit logging: HIPAA requires logging all access to patient records (who, when, what)
  2. Field-level access control: Not all users can see all fields (e.g., SSN)
  3. Break-glass access: Emergency access with additional logging
  4. Data minimization: Should not return full patient list (pagination not enough)
  5. Consent verification: Patient must consent to data access
  6. Encryption at rest and in transit: Not specified in API design

The Right Design (Human-Led):

GET /api/v1/patients/{id}
  Auth: Bearer token + role + purpose
  Headers:
    - X-Access-Purpose: treatment | payment | operations | emergency
    - X-User-Role: doctor | nurse | admin
  Response: 200 OK with field-filtered patient data
  Audit: Log access (user, patient, purpose, timestamp, IP)

GET /api/v1/patients
  Auth: Bearer token + elevated permissions
  Query: 
    - search: string (required, min 3 chars)  # No "list all"
    - fields: string (limit returned fields)
  Response: 200 OK with search results (max 20)
  Audit: Log search (user, query, results count)

PUT /api/v1/patients/{id}
  Auth: Bearer token + write permission
  Headers:
    - X-Update-Reason: required (audit trail)
  Body: { patient data }
  Response: 200 OK
  Audit: Log update (user, patient, fields changed, reason)

# Compliance Features
- All responses encrypted (TLS 1.3)
- Audit logs immutable, retained 7 years
- Field-level access control (role-based)
- No bulk exports (HIPAA data minimization)
- Rate limiting (prevent data harvesting)
- Consent verification before data access

AI can't design this because it doesn't understand:

  • HIPAA requirements (audit, consent, minimization)
  • Your organization's policies (access purposes, roles)
  • Threat model (data harvesting, insider threats)
  • Compliance timelines (7-year retention)

The Right Approach:

  1. Have AI generate the basic API
  2. Engage security/compliance team
  3. Layer in compliance requirements
  4. Document security controls

Don't trust AI for security-critical APIs. It's a starting point, not the final design.

The Hybrid Approach That Works

Here's my workflow for AI-assisted API design:

Step 1: Use AI for Structure (10 minutes)

Prompt:

Design REST API for [domain].

Existing patterns:
[Paste your existing API patterns - pagination, errors, auth]

New resources:
[Describe resources and operations]

Generate:
1. Endpoint structure (URLs, methods)
2. Request/response formats
3. OpenAPI spec
4. Consistent with existing patterns

Output: Basic API structure, consistent with existing patterns.

Step 2: Human Review for Domain Boundaries (30 minutes)

Ask yourself:

  • Are these the right resources? (Not too fine-grained, not too coarse)
  • Will this structure support future features?
  • Are relationships between resources clear?
  • Is this the right level of coupling?

Refine the resource model if needed.

Step 3: AI Generates Detailed Spec (10 minutes)

Prompt:

Generate complete OpenAPI spec for:
[Paste refined resource model]

Include:
- All CRUD operations
- Pagination, filtering, sorting
- Error responses
- Request/response examples
- Authentication/authorization

Output: Complete OpenAPI spec (300-500 lines).

Step 4: Human Review for Evolution (20 minutes)

Ask yourself:

  • What will we add in 1 year? 3 years?
  • What URL structure changes would break clients?
  • What field additions are easy? Hard?
  • Do we need versioning strategy?

Adjust for evolution (add extensibility, metadata fields, version prefix).

Step 5: AI Generates Implementation Skeleton (10 minutes)

Prompt:

Generate [language/framework] implementation for this API:
[Paste OpenAPI spec]

Generate:
- Controller/route handlers
- Request/response DTOs
- Validation logic
- Error handling

Output: Implementation skeleton (80% complete).

Step 6: Human Adds Business Logic (Hours/Days)

This is where you write actual code:

  • Database queries
  • Business rules
  • External integrations
  • Performance optimizations
  • Security controls

AI doesn't do this well. You write it.

Step 7: AI Generates Tests (20 minutes)

Prompt:

Generate tests for this API implementation:
[Paste implementation]

Include:
- Happy path tests
- Validation error tests
- Not found tests
- Permission tests

Output: Test suite (review and refine).

Total Time: ~2 hours (vs. 8-9 hours traditional)

AI saved 6-7 hours. But the critical thinking (domain modeling, evolution, security) was still human-led.

Real Example: Order API

Let me walk through a real API design I did last month.

Step 1: AI Generates Structure (8 minutes)

Prompt:

Design Order API for e-commerce platform.

Existing patterns:
- Pagination: page/size query params
- Errors: Standardized error format with field-level details
- Auth: Bearer token

Operations needed:
- Create order
- Get order by ID
- List orders for user
- Update order status (admin only)
- Cancel order

Generate endpoint structure and basic request/response formats.

AI Response:

POST   /api/v1/orders
GET    /api/v1/orders/{id}
GET    /api/v1/orders
PATCH  /api/v1/orders/{id}/status
DELETE /api/v1/orders/{id}

Step 2: Human Refines (25 minutes)

My Changes:

  1. Changed DELETE to POST for cancel:

    • Reason: Cancel is not idempotent (might trigger refund). POST is more appropriate.
    • Changed: DELETE /api/v1/orders/{id}POST /api/v1/orders/{id}/cancel
  2. Added order fulfillment endpoints:

    • Reason: Orders have lifecycle (placed → paid → fulfilled → delivered). Need to track fulfillment.
    • Added: POST /api/v1/orders/{id}/fulfill and POST /api/v1/orders/{id}/deliver
  3. Added payment relationship:

    • Reason: Orders and payments are separate resources (different teams own them).
    • Added: paymentId field in order, separate payment API
  4. Added customer context:

    • Reason: Users can create orders for themselves, but admins can create orders for any customer.
    • Added: customerId field, permission checks

Refined Structure:

POST   /api/v1/orders                    # Create order
GET    /api/v1/orders/{id}               # Get order
GET    /api/v1/orders                    # List orders
POST   /api/v1/orders/{id}/cancel        # Cancel order
POST   /api/v1/orders/{id}/fulfill       # Mark fulfilled (admin)
POST   /api/v1/orders/{id}/deliver       # Mark delivered (admin)

Step 3: AI Generates OpenAPI Spec (12 minutes)

Prompt:

Generate OpenAPI 3.0 spec for Order API:

[Pasted refined structure above]

Order schema:
- id: UUID
- customerId: UUID
- items: array of { productId, quantity, price }
- subtotal: number
- tax: number
- shipping: number
- total: number
- status: enum (pending, paid, fulfilled, delivered, cancelled)
- paymentId: UUID (nullable, links to payment API)
- shippingAddress: object { street, city, state, zip }
- createdAt: datetime
- updatedAt: datetime

Include:
- Complete request/response schemas
- Error responses
- Examples
- Pagination for list endpoint

AI Response:

Generated 400-line OpenAPI spec. I reviewed and made minor tweaks (fixed one enum value, added missing required field).

Step 4: Human Reviews for Evolution (15 minutes)

Questions I Asked Myself:

  1. Will order structure change?

    • Answer: Yes. Future features: gift messages, split shipments, multiple payments.
    • Action: Added metadata field (JSON object) for extensibility.
  2. Will we add more status transitions?

    • Answer: Probably. Returns, partial refunds, split shipments.
    • Action: Designed status transitions as separate endpoints (easy to add new transitions).
  3. Will we need versioning?

    • Answer: Maybe. If order schema changes significantly.
    • Action: Used /api/v1/ prefix. Documented versioning strategy.

Adjustments:

  • Added metadata field (extensibility)
  • Documented status transition flow (documentation for future developers)
  • Planned for v2 if needed (documented breaking vs. non-breaking changes)

Step 5: AI Generates Implementation (15 minutes)

Prompt:

Generate Node.js/Express implementation for Order API:

[Pasted OpenAPI spec]

Use:
- Express.js
- TypeScript
- PostgreSQL (via Prisma)
- JWT authentication

Generate:
- Route handlers
- DTOs (request/response types)
- Validation (express-validator)
- Error handling middleware

AI Response:

Generated complete implementation skeleton:

  • routes/orders.ts (150 lines)
  • controllers/orders.controller.ts (300 lines)
  • dto/orders.dto.ts (100 lines)
  • middleware/auth.ts (50 lines)
  • middleware/error.ts (80 lines)

I reviewed and refined (added database queries, business logic, permission checks). Implementation was 70% complete from AI.

Step 6: Human Adds Business Logic (4 hours)

What I Added:

  • Database queries (Prisma)
  • Business rules:
    • Can only cancel order if status is "pending" or "paid"
    • Can only fulfill order if status is "paid"
    • Can only deliver order if status is "fulfilled"
  • Payment integration (call payment API to verify payment)
  • Inventory checks (ensure products are in stock)
  • Email notifications (order confirmation, shipping updates)
  • Audit logging (order state changes)

This is where AI can't help much. Domain-specific business logic.

Step 7: AI Generates Tests (18 minutes)

Prompt:

Generate tests for Order API implementation:

[Pasted implementation]

Generate:
- Happy path tests (create, get, list, cancel)
- Validation tests (missing fields, invalid data)
- Permission tests (user vs. admin)
- Status transition tests (can't fulfill unpaid order)
- Integration tests (with payment API)

Use Jest and Supertest.

AI Response:

Generated 45 test cases. I reviewed and added 8 more (edge cases AI missed). 85% of tests were production-ready.

Total Time

  • Step 1 (AI structure): 8 minutes
  • Step 2 (Human refinement): 25 minutes
  • Step 3 (AI OpenAPI): 12 minutes
  • Step 4 (Human evolution): 15 minutes
  • Step 5 (AI implementation): 15 minutes
  • Step 6 (Human business logic): 4 hours
  • Step 7 (AI tests): 18 minutes

Total: ~5.5 hours

Traditional approach: 10-12 hours (based on previous similar APIs)

Time saved: 4.5-6.5 hours (45-55%)

When to Use AI, When to Use Human Judgment

Use AI For:

Consistency

  • Applying existing patterns to new resources
  • Maintaining naming conventions
  • Standardizing error responses

Boilerplate

  • OpenAPI spec generation
  • Request/response DTOs
  • Validation schemas
  • Route handler skeletons

Common Patterns

  • Pagination (offset, cursor)
  • Filtering and sorting
  • CRUD operations
  • Error handling

Documentation

  • API docs from code
  • Request/response examples
  • Error response catalogs

Use Human Judgment For:

🧠 Domain Modeling

  • Resource boundaries (what should be separate resources?)
  • Relationships (embedded vs. referenced?)
  • Aggregates (what data belongs together?)

🧠 Evolution Strategy

  • What will change in 1-3 years?
  • How to version (URL vs. header vs. media type?)
  • What's hard to change later?

🧠 Performance Trade-offs

  • Pagination strategy (offset vs. cursor vs. materialized)
  • Data fetching (N+1 queries, eager loading, caching)
  • Scale considerations (1K users vs. 1M users)

🧠 Security and Compliance

  • Authentication strategy (OAuth, JWT, API keys)
  • Authorization (RBAC, ABAC, ACL)
  • Compliance requirements (GDPR, HIPAA, PCI DSS)
  • Threat modeling (what attacks to defend against)

🧠 Business Logic

  • Domain rules (what's valid in your business context)
  • Workflow (order lifecycle, state transitions)
  • Integration with other systems

Checklist: AI-Assisted API Design

Use this checklist for every API design:

Phase 1: AI Generation (30 minutes)

  • Use AI to generate basic structure (URLs, methods)
  • Use AI to generate OpenAPI spec
  • Use AI to generate implementation skeleton
  • Use AI to generate test cases

Phase 2: Human Review (1-2 hours)

  • Review resource boundaries (right level of granularity?)
  • Review evolution strategy (what changes in 1-3 years?)
  • Review performance implications (scale to 10x, 100x?)
  • Review security requirements (auth, authz, compliance)
  • Review business logic (domain rules correct?)
  • Add missing edge cases (AI missed these)

Phase 3: Implementation (Hours/Days)

  • Add database queries
  • Add business logic
  • Add external integrations
  • Add performance optimizations
  • Add security controls
  • Add monitoring and logging

Phase 4: Validation (1-2 hours)

  • Test happy paths
  • Test error scenarios
  • Test performance (load testing)
  • Test security (penetration testing)
  • Review with team (architecture review)

Common Mistakes

Mistake 1: Trusting AI for Security

AI generates secure-looking APIs (Bearer tokens, HTTPS). But it misses:

  • Field-level access control
  • Audit logging
  • Data minimization
  • Compliance requirements

Always review security with a security expert, not just AI.

Mistake 2: Over-Engineering Based on AI Suggestions

AI often suggests features you don't need:

  • Complex filtering (when simple search works)
  • Multiple pagination strategies (when one is enough)
  • Extensive sorting options (when default sort is fine)

Add complexity when needed, not because AI suggested it.

Mistake 3: Accepting First API Design

AI's first design is rarely optimal. Always iterate:

  • Ask follow-up questions
  • Challenge assumptions
  • Generate alternatives
  • Compare trade-offs

Treat AI as a brainstorming partner, not a final decision-maker.

Mistake 4: Ignoring Long-Term Evolution

AI designs for today's requirements. It doesn't think 3 years ahead.

Always ask: What will change? How will this API evolve?

Design the hard-to-change parts (URLs, resource names) for evolution. Use extensibility (metadata fields, versioning) for flexibility.

The Bottom Line

AI-assisted API design is faster and more consistent than manual design. But it still requires human judgment for domain modeling, evolution strategy, performance trade-offs, and security.

The Hybrid Approach:

  1. AI generates structure, spec, and boilerplate (30-60 minutes)
  2. Human reviews domain model, evolution, security (1-2 hours)
  3. Human implements business logic (hours/days)
  4. AI generates tests (15-30 minutes)

Time savings: 40-60% compared to traditional API design.

Quality improvement: More consistent, fewer missed edge cases, better documentation.

But: Critical thinking still required. AI accelerates, it doesn't replace judgment.

Use AI for speed and consistency. Use human expertise for taste and trade-offs.

Start with your next API design. Use this workflow. Track time saved. You'll never go back to pure manual design.

Topics

api-designrest-apiapi-developmentsoftware-architectureopenapiapi-best-practicesai-assisted-development
Ruchit Suthar

About Ruchit Suthar

15+ years scaling teams from startup to enterprise. 1,000+ technical interviews, 25+ engineers led. Real patterns, zero theory.