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:
| Parameter | Type | Example | Description |
|---|---|---|---|
filter[field] | string | filter[status]=published | Exact match filter |
filter[field][op] | string | filter[price][gte]=10 | Operator filter |
sort | string | sort=-createdAt,title | Sort (comma-separated, - for desc) |
limit | integer | limit=25 | Items per page (1-1000, default 50) |
page | integer | page=2 | Page number (1-indexed) |
offset | integer | offset=50 | Alternative to page |
search | string | search=kubernetes | Full-text search (if enabled) |
include | string | include=author,tags | Eager-load relationships |
scope | string | scope=deleted | Named scope (soft delete) |
fields | string | fields=id,title,status | Sparse 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:
| Parameter | Example | Description |
|---|---|---|
include | include=author,tags | Eager-load relationships |
fields | fields=id,title,status | Sparse 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
deletedAttimestamp - 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
hasMany — List Related
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
}
}
belongsToMany — Link
POST /api/v1/{domain}/{resources}/{id}/{relationship}
Request:
{
"tagId": "tag-uuid"
}
Response (200):
{
"status": "ok",
"code": 200,
"data": {
"linked": true
}
}
belongsToMany — Unlink
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:
| Parameter | Description |
|---|---|
limit | Max records (default 100) |
offset | Pagination 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:
| Parameter | Description |
|---|---|
limit | Max events (default 100) |
offset | Pagination offset |
event | Filter 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}— ListPOST /{parentId}/{children}— Create (auto-sets foreign key)GET /{parentId}/{children}/{childId}— GetPATCH /{parentId}/{children}/{childId}— UpdateDELETE /{parentId}/{children}/{childId}— Delete
40.11 Complete Endpoint Count Example
A blog Post resource with full features enabled generates:
| Category | Endpoints | Count |
|---|---|---|
| Standard CRUD | list, get, create, update, put, delete, count, distinct, bulk × 3 | 11 |
| Relationships | comments (list), tags (list/link/unlink) | 4 |
| State Machine | publish, archive, restore transitions | 3 |
| Custom Operations | sendReminder | 1 |
| Soft Delete | restore | 1 |
| Audit | audit trail | 1 |
| History | history events | 1 |
| Total | 22 |
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
| Feature | Endpoints 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 Access | Parent/child resource paths |
End of Chapter 40.
End of ADL v0.3 Specification.