For AI agents: the complete documentation index is available at /hclapi/llms.txt, the full documentation bundle is available at /hclapi/llms-full.txt, and this page is available as Markdown at /hclapi/docs/manifest/schemas.md.

schema

Declares structural, type, and semantic validation rules for incoming requests. Validation runs during request ingress before the pipeline begins execution.

Declaration

schema "user_create" {
  field "email" {
    type        = string
    required    = true
    format      = "email"
    description = "Primary user login and notification email"
  }

  field "account_type" {
    type     = string
    required = true
    enum     = ["individual", "business"]
  }

  field "username" {
    type       = string
    required   = true
    min_length = 3
    max_length = 30
    pattern    = "^[a-zA-Z0-9_-]+$"
  }

  field "age" {
    type     = int
    required = false
    min      = 18
    max      = 120
  }

  field "role" {
    type    = string
    default = "member"
  }

  field "tags" {
    type         = list(string)
    required     = false
    min_items    = 1
    max_items    = 10
    unique_items = true
  }
}

The schema is referenced in endpoint definitions as schema.<name>.

Field attributes & constraints

All field constraints map 1:1 to OpenAPI 3.1 / JSON Schema standards:

AttributeTypeApplicable typesDefaultDescription
typetypeAllrequiredExpected data type (string, int, float, bool, any, list(...), map(...))
requiredboolAllfalseIf true, rejects the request with HTTP 422 if the field is missing
defaultanyOptional fieldsnullFallback value injected automatically if field is absent
descriptionstringAllnullHuman-readable explanation exported to OpenAPI documentation
enumliststring, int, floatnullRestricts allowed values to an explicit list
formatstringstringnullStandard OpenAPI format constraint (see below)
patternstringstringnullRegular expression pattern the string must match
min_lengthintstringnullMinimum string character length
max_lengthintstringnullMaximum string character length
minnumberint, floatnullMinimum numeric value (inclusive)
maxnumberint, floatnullMaximum numeric value (inclusive)
min_itemsintlistnullMinimum number of items in a list
max_itemsintlistnullMaximum number of items in a list
unique_itemsboollistfalseIf true, requires all elements in the list to be unique

Built-in format validators

FormatDescriptionExample valid value
"email"RFC 5322 email address"jane@example.com"
"uuid"UUID v4 / v7 identifier"f47ac10b-58cc-4372-a567-0e02b2c3d479"
"uri"RFC 3986 absolute URI"https://api.example.com/callback"
"date-time"RFC 3339 / ISO 8601 timestamp"2026-08-31T20:00:00Z"
"date"RFC 3339 full-date (YYYY-MM-DD)"2026-08-31"
"ipv4"Dotted-decimal IPv4 address"192.168.1.1"
"ipv6"Colon-separated IPv6 address"2001:0db8:85a3::8a2e:0370:7334"
"hostname"RFC 1123 Hostname / FQDN"api.service.internal"

Binding schemas to endpoints

Named schema reference

endpoint "POST /api/v1/users" {
  request {
    body = schema.user_create
  }

  pipeline {
    sql "insert_user" {
      connection = connection.postgres.main
      query      = "INSERT INTO users (email, name, role) VALUES (@email, @name, @role) RETURNING id"
      args = {
        email = ctx.request.body.email
        name  = ctx.request.body.username
        role  = ctx.request.body.role # Automatically receives default "member" if omitted
      }
    }

    respond {
      status = 201
      body   = steps.insert_user.row
    }
  }
}

Inline parameter validation (Path, Query, Headers)

endpoint "GET /api/v1/search" {
  request {
    headers {
      field "x-api-key" {
        type     = string
        required = true
        format   = "uuid"
      }
    }
    query {
      field "q" {
        type       = string
        required   = true
        min_length = 2
      }
      field "limit" {
        type    = int
        default = 20
        min     = 1
        max     = 100
      }
      field "sort" {
        type    = string
        default = "desc"
        enum    = ["asc", "desc"]
      }
    }
  }

  pipeline {
    respond {
      status = 200
      body = {
        query = ctx.request.query.q
        limit = ctx.request.query.limit
        sort  = ctx.request.query.sort
      }
    }
  }
}
Header case-insensitivity (RFC 9110)

HTTP field names are case-insensitive. You can declare header fields in any casing:

headers {
  field "Authorization" {
    type     = string
    required = true
  }
  field "X-Trace-Sampled" {
    type    = bool
    default = true
  }
}

Validation failure responses (HTTP 422)

When an incoming payload violates schema constraints, execution halts immediately before the pipeline runs. The engine returns an RFC 9457 Problem Details object detailing every failed constraint:

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/problem+json

{
  "type": "urn:hclapi:error:validation-error",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "Request payload failed schema validation constraints",
  "instance": "/api/v1/users",
  "invalid_params": [
    {
      "name": "email",
      "reason": "must be a valid email format"
    },
    {
      "name": "account_type",
      "reason": "must be one of: [\"individual\", \"business\"]"
    },
    {
      "name": "username",
      "reason": "length must be at least 3 characters"
    },
    {
      "name": "age",
      "reason": "must be greater than or equal to 18"
    }
  ]
}