Chapter 40 · Volume V — Reference

Complete API Reference

40.1 Overview

This chapter documents every endpoint generated by ADL for each resource. Understanding the complete API surface is essential for client development, testing, and integration.

ADL generates endpoints based on resource configuration. A fully-featured resource with relationships, state machine, soft delete, and audit enabled can generate 25+ endpoints.


40.2 Standard CRUD Endpoints

Every resource generates up to 11 standard endpoints unless explicitly disabled.

List

GET /api/v1/{domain}/{resources}

Query Parameters:

ParameterTypeExampleDescription
filter[field]stringfilter[status]=publishedExact match filter
filter[field][op]stringfilter[price][gte]=10Operator filter
sortstringsort=-createdAt,titleSort (comma-separated, - for desc)
limitintegerlimit=25Items per page (1-1000, default 50)
pageintegerpage=2Page number (1-indexed)
offsetintegeroffset=50Alternative to page
searchstringsearch=kubernetesFull-text search (if enabled)
includestringinclude=author,tagsEager-load relationships
scopestringscope=deletedNamed scope (soft delete)
fieldsstringfields=id,title,statusSparse fieldset

Filter Operators: eq (default), ne, gt, gte, lt, lte, like, in

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "items": [
      { "id": "uuid", "title": "Post 1", ... }
    ],
    "count": 15,
    "meta": {
      "total": 42,
      "page": 1,
      "per_page": 50,
      "total_pages": 1,
      "has_next": false,
      "has_prev": false
    }
  }
}

Disable: api.disable: [list]

Get

GET /api/v1/{domain}/{resources}/{id}

Query Parameters:

ParameterExampleDescription
includeinclude=author,tagsEager-load relationships
fieldsfields=id,title,statusSparse fieldset

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "id": "uuid",
    "title": "My Post",
    "status": "published",
    "createdAt": "2026-01-01T00:00:00Z"
  }
}

Errors:

  • 404 NOT_FOUND — Record does not exist

Disable: api.disable: [get]

Create

POST /api/v1/{domain}/{resources}

Request:

{
  "title": "New Post",
  "body": "Content here",
  "status": "draft"
}

Response (201):

{
  "status": "ok",
  "code": 201,
  "data": {
    "id": "generated-uuid",
    "title": "New Post",
    "body": "Content here",
    "status": "draft",
    "createdAt": "2026-05-17T14:30:00Z",
    "updatedAt": "2026-05-17T14:30:00Z"
  }
}

Errors:

  • 422 VALIDATION_ERROR — Field validation failed
  • 409 DUPLICATE — Unique constraint violation

Disable: api.disable: [create]

Update (Partial)

PATCH /api/v1/{domain}/{resources}/{id}

Request: Only fields being changed

{
  "title": "Updated Title"
}

Response (200): Full updated record

Errors:

  • 404 NOT_FOUND
  • 422 VALIDATION_ERROR
  • 403 FORBIDDEN — Field write-protected or operation not permitted

Disable: api.disable: [update]

Replace (Full)

PUT /api/v1/{domain}/{resources}/{id}

Request: Complete record (all required fields)

Response (200): Full updated record

Disable: api.disable: [put]

Delete

DELETE /api/v1/{domain}/{resources}/{id}

Soft Delete Enabled:

  • Sets deletedAt timestamp
  • Record remains queryable with scope=deleted
  • Response (204): No content

Hard Delete:

  • Removes record permanently
  • Response (204): No content

Errors:

  • 404 NOT_FOUND
  • 403 FORBIDDEN

Disable: api.disable: [delete]

Count

GET /api/v1/{domain}/{resources}/count

Accepts same filters as list endpoint.

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "total": 42
  }
}

Disable: api.disable: [count]

Distinct

GET /api/v1/{domain}/{resources}/distinct/{field}

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "field": "status",
    "values": ["draft", "published", "archived"]
  }
}

Disable: api.disable: [distinct]

Bulk Create

POST /api/v1/{domain}/{resources}/bulk

Request:

{
  "items": [
    { "title": "Post 1", "body": "..." },
    { "title": "Post 2", "body": "..." }
  ]
}

Response (201):

{
  "status": "ok",
  "code": 201,
  "data": {
    "created": 2,
    "items": [
      { "id": "uuid-1", ... },
      { "id": "uuid-2", ... }
    ]
  }
}

Disable: api.disable: [bulk]

Bulk Update

PATCH /api/v1/{domain}/{resources}/bulk

Request:

{
  "ids": ["uuid-1", "uuid-2"],
  "data": {
    "status": "archived"
  }
}

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "updated": 2
  }
}

Disable: api.disable: [bulk]

Bulk Delete

DELETE /api/v1/{domain}/{resources}/bulk

Request:

{
  "ids": ["uuid-1", "uuid-2"]
}

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "deleted": 2
  }
}

Disable: api.disable: [bulk]


40.3 Relationship Endpoints

GET /api/v1/{domain}/{resources}/{id}/{relationship}

Example: GET /api/v1/blog/posts/{postId}/comments

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "items": [
      { "id": "comment-1", "postId": "post-uuid", "body": "..." }
    ],
    "count": 5
  }
}

belongsToMany — List Linked

GET /api/v1/{domain}/{resources}/{id}/{relationship}

Example: GET /api/v1/blog/posts/{postId}/tags

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "items": [
      { "id": "tag-1", "name": "Technology" },
      { "id": "tag-2", "name": "News" }
    ],
    "count": 2
  }
}
POST /api/v1/{domain}/{resources}/{id}/{relationship}

Request:

{
  "tagId": "tag-uuid"
}

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "linked": true
  }
}
DELETE /api/v1/{domain}/{resources}/{id}/{relationship}/{relatedId}

Example: DELETE /api/v1/blog/posts/{postId}/tags/{tagId}

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "unlinked": true
  }
}

40.4 Embedded Resources

The include parameter eager-loads relationships:

GET /api/v1/blog/posts/{id}?include=author,tags,comments

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "id": "post-uuid",
    "title": "My Post",
    "authorId": "author-uuid",
    "author": {
      "id": "author-uuid",
      "name": "Alice",
      "email": "alice@example.com"
    },
    "tags": [
      { "id": "tag-1", "name": "Technology" },
      { "id": "tag-2", "name": "News" }
    ],
    "comments": [
      { "id": "comment-1", "body": "Great post!", "createdAt": "..." }
    ]
  }
}

Rules:

  • belongsTo: Embedded as single object
  • hasMany: Embedded as array
  • belongsToMany: Embedded as array
  • Nested includes: include=author.organization (if supported)
  • Performance: Each include adds a JOIN or additional query

40.5 State Machine Endpoints

For each transition, a dedicated endpoint is generated:

POST /api/v1/{domain}/{resources}/{id}/transitions/{transitionName}

Example: POST /api/v1/blog/posts/{id}/transitions/publish

Request (if required fields exist):

{
  "publishedAt": "2026-05-17T14:30:00Z",
  "publisherNotes": "Ready for publication"
}

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "id": "post-uuid",
    "status": "published",
    "publishedAt": "2026-05-17T14:30:00Z",
    "updatedAt": "2026-05-17T14:30:00Z"
  }
}

Errors:

  • 403 GUARD_FAILED — User lacks required role
  • 422 INVALID_TRANSITION — Not available from current state
  • 422 REQUIRED_FIELD_MISSING — Transition requires fields not provided

40.6 Custom Operations

Custom operations (§17) generate endpoints with configured method/path:

api:
  custom:
    sendReminder:
      method: POST
      path: /:id/send-reminder

Generated endpoint:

POST /api/v1/{domain}/{resources}/{id}/send-reminder

Request/Response: Defined by operation implementation


40.7 Soft Delete Restore

When features.softDelete: true:

POST /api/v1/{domain}/{resources}/{id}/restore

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "restored": true,
    "record": {
      "id": "uuid",
      "title": "Restored Post",
      "deletedAt": null
    }
  }
}

Errors:

  • 404 NOT_FOUND — Record not found or not deleted
  • 403 FORBIDDEN

40.8 Audit Trail

When features.audit: true:

GET /api/v1/{domain}/{resources}/{id}/audit

Query Parameters:

ParameterDescription
limitMax records (default 100)
offsetPagination offset

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "items": [
      {
        "id": "audit-uuid",
        "recordId": "post-uuid",
        "operation": "update",
        "userId": "user-uuid",
        "username": "alice",
        "changes": {
          "status": { "from": "draft", "to": "published" },
          "publishedAt": { "from": null, "to": "2026-05-17T14:30:00Z" }
        },
        "timestamp": "2026-05-17T14:30:00Z"
      }
    ],
    "count": 5
  }
}

40.9 History

When declarative history is enabled (§21):

GET /api/v1/{domain}/{resources}/{id}/history

Query Parameters:

ParameterDescription
limitMax events (default 100)
offsetPagination offset
eventFilter by event name

Response (200):

{
  "status": "ok",
  "code": 200,
  "data": {
    "items": [
      {
        "id": "history-uuid",
        "event": "published",
        "label": "Post published by Alice",
        "severity": "info",
        "actor": "alice",
        "timestamp": "2026-05-17T14:30:00Z",
        "data": {
          "publishedAt": "2026-05-17T14:30:00Z"
        }
      }
    ],
    "count": 12
  }
}

40.10 Nested Resource Access

Resources can be accessed through parent relationships:

GET /api/v1/{domain}/{parentResource}/{parentId}/{childResource}

Example: GET /api/v1/blog/posts/{postId}/comments

This is equivalent to:

GET /api/v1/blog/comments?filter[postId]={postId}

But provides clearer semantics and automatic validation that the parent exists.

Supported Operations:

  • GET /{parentId}/{children} — List
  • POST /{parentId}/{children} — Create (auto-sets foreign key)
  • GET /{parentId}/{children}/{childId} — Get
  • PATCH /{parentId}/{children}/{childId} — Update
  • DELETE /{parentId}/{children}/{childId} — Delete

40.11 Complete Endpoint Count Example

A blog Post resource with full features enabled generates:

CategoryEndpointsCount
Standard CRUDlist, get, create, update, put, delete, count, distinct, bulk × 311
Relationshipscomments (list), tags (list/link/unlink)4
State Machinepublish, archive, restore transitions3
Custom OperationssendReminder1
Soft Deleterestore1
Auditaudit trail1
Historyhistory events1
Total22

With nested access (comments under posts), add 5 more endpoints = 27 total.


40.12 Endpoint Discovery

All endpoints for a domain are documented in:

GET /api/v1/domains/{domain}/openapi.json

The OpenAPI spec (§37) provides:

  • Complete endpoint list with methods
  • Request/response schemas
  • Query parameters
  • Authentication requirements
  • Error responses

40.13 Integration Points

FeatureEndpoints Generated
Relationships (§08)hasMany list, belongsToMany list/link/unlink
State Machines (§12)One POST per transition
Soft Delete (§7)restore endpoint, scope query parameter
Audit (§8)Per-resource audit trail endpoint
History (§21)Per-resource history endpoint
Custom Operations (§17)Configured method/path
Nested AccessParent/child resource paths

End of Chapter 40.

End of ADL v0.3 Specification.