---
title: API Reference
---

Quick reference for the core Ack classes, methods, and annotations. For detailed explanations and examples, see the specific guides linked below.

## Core `Ack` Class

Entry point for creating schemas. See [Schema Types](../core-concepts/schemas.mdx).

- `Ack.string()`: Creates a `StringSchema` for validating `String` values.
- `Ack.integer()`: Creates an `IntegerSchema` for validating `int` values. Rejects `double` (e.g. `42.0`).
- `Ack.double()`: Creates a `DoubleSchema` for validating `double` values. Rejects `int` (e.g. `42`).
- `Ack.number()`: Creates a `NumberSchema` for validating any `num` value (accepts both `int` and `double`).
- `Ack.boolean()`: Creates a `BooleanSchema` for validating `bool` values.
- `Ack.list(AckSchema itemSchema)`: Creates a `ListSchema` for validating arrays. Nullable item schemas are not supported; make the list itself nullable instead.
- `Ack.object(Map<String, AckSchema> properties)`: Creates an `ObjectSchema` for validating objects.
- `Ack.enumValues(List<T> values)`: Creates an `EnumSchema<T>` for Dart enum
  types. Accepts enum instances, string names, or indices. **Preferred over
  `enumString` when a Dart enum exists.**
- `Ack.enumCodec(List<T> values)`: Like `enumValues`, but returns a
  `CodecSchema<String, T>` instead of an `EnumSchema<T>`. Use this when
  downstream code expects every value-shape to be a `CodecSchema` (e.g. a
  registry of codecs). The decode and encode functions are identity — the
  underlying `EnumSchema` still maps between `T` and the enum's `.name`.
- `Ack.enumString(List<String> values)`: Creates a `StringSchema` constrained
  to the given values. For ad-hoc string lists without a backing Dart enum.
- `Ack.anyOf(List<AckSchema> schemas)`: Creates an `AnyOfSchema` for union types.
- `Ack.any()`: Creates an `AnySchema` that accepts any non-null JSON-safe
  value. Chain `.nullable()` to allow `null`.
- `Ack.instance<T extends Object>()`: Creates a schema that checks a value is a
  Dart instance of `T` (runtime type check; handy as a codec `output` schema).
- `Ack.codec(...)` / `Ack.date()` / `Ack.datetime()` / `Ack.uri()` /
  `Ack.duration()` / `Ack.enumCodec(...)`: Create codecs. See
  [Codecs](../core-concepts/codecs.mdx).
- `Ack.lazy(String name, AckSchema Function() builder)`: Creates a memoized
  deferred schema reference for recursive schema graphs. JSON Schema export
  renders Draft-7 `definitions` / `$ref` entries using `name`.
- `Ack.discriminated<T extends Object>(...)`: Creates a discriminated union
  schema. Branches may be plain `ObjectSchema` or transformed schemas whose
  base is an `ObjectSchema`. The union owns the discriminator: branches normally
  omit it, boundary payloads must include it, compatible branch discriminator
  fields are allowed, and conflicts are rejected. Exported/generated branches
  expose the exact branch literal.

## `AckSchema<Boundary, Runtime>` (Base Class)

Base class for all schema types.

### Primary Validation Methods

- `SchemaResult<Runtime> safeParse(Object? data, {String? debugName})`: Validates `data` and returns a `SchemaResult`. Never throws; use `.getOrNull()` to get the value without risk of an exception.
- `Runtime? parse(Object? data, {String? debugName})`: Validates `data` and returns the value; throws `AckException` on failure.
- `SchemaResult<TOut> safeParseAs<TOut extends Object>(Object? data, TOut Function(Runtime?) map, {String? debugName})`: Parses and maps the validated value to `TOut`.
- `TOut parseAs<TOut extends Object>(Object? data, TOut Function(Runtime?) map, {String? debugName})`: Throwing variant of `safeParseAs`.
- `SchemaResult<Boundary> safeEncode(Runtime? value, {String? debugName})`: Encodes a runtime value to the boundary representation.
- `Boundary? encode(Runtime? value, {String? debugName})`: Throwing variant of `safeEncode`.

### Schema Modification Methods

- `AckSchema<Boundary, Runtime> nullable({bool value = true})`: Returns a new schema that also accepts `null`.
- `AckSchema<Boundary, Runtime> optional({bool value = true})`: Returns a new schema marked as optional (for object fields).
- `AckSchema<Boundary, Runtime> describe(String description)`: Attaches a description for documentation and JSON Schema generation.
- `DefaultSchema<Boundary, Runtime> withDefault(Runtime value)`: Wraps the schema in a `DefaultSchema` that supplies `value` when the parse input is `null`.

Primitive schemas (`StringSchema`, `IntegerSchema`, `DoubleSchema`, `NumberSchema`, `BooleanSchema`) are strict — they reject values whose Dart runtime type doesn't match. `IntegerSchema` and `DoubleSchema` do not overlap (`42.0` fails `Ack.integer()`, `42` fails `Ack.double()`); use `Ack.number()` when either is acceptable. For non-`num` boundary types (e.g. numeric strings), use [`transform`](../core-concepts/schemas.mdx#transformations) or [`codec`](#codecschemaboundary-runtime) to convert before validation.

### Custom Validation Methods

- `AckSchema<Boundary, Runtime> constrain(Constraint<Runtime> constraint, {String? message})`: Adds a constraint and optionally overrides its message. The constraint must mix in `Validator<Runtime>`, or an `ArgumentError` is thrown.
- `AckSchema<Boundary, Runtime> withConstraint(Constraint<Runtime> constraint)`: Adds a constraint directly (no message override; `constrain` delegates here).
- `AckSchema<Boundary, Runtime> refine(bool Function(Runtime) validate, {String message = 'The value did not pass the custom validation.'})`: Adds a custom validation predicate with an optional error message.
- `CodecSchema<Boundary, R> transform<R>(R Function(Runtime) transformer)`: Transforms validated runtime values to `R` (parse-only; encode fails).

### Utility Methods

- `Map<String, Object?> toJsonSchema()`: Returns a Draft-7 JSON Schema map via the canonical `AckSchemaModel` boundary.
- `Map<String, Object?> toMap()`: Serializes the schema for debugging.

See also [Schema Types](../core-concepts/schemas.mdx) for detailed usage examples.

## `StringSchema`

Schema for validating strings. See [String Validation](../core-concepts/validation.mdx#string-constraints).

### Length Constraints

- `minLength(int min)`: Minimum string length
- `maxLength(int max)`: Maximum string length
- `length(int exact)`: Exact string length
- `notEmpty()`: String must not be empty (equivalent to `minLength(1)`)

### Pattern Matching

- `matches(String pattern, {String? example, String? message})`: Must match a regex pattern. Patterns are not automatically anchored — use `^...$` for full-string matching. See [String validation](../core-concepts/validation.mdx#string-constraints) for details.
- `contains(String pattern, {String? example, String? message})`: Must contain the pattern anywhere in the string.
- `startsWith(String value)`: Must start with `value`.
- `endsWith(String value)`: Must end with `value`.

### Format Validation

- `email()`: Must be valid email format
- `url()`: Must be valid URL format (alias for `uri()`)
- `uri()`: Must be valid URI according to RFC 3986
- `uuid()`: Must be valid UUID format
- `ip({int? version})`: Must be valid IP address (version 4 or 6)
- `ipv4()`: Must be valid IPv4 address
- `ipv6()`: Must be valid IPv6 address

### Date and Time

- `date()`: Must be valid ISO 8601 date (YYYY-MM-DD)
- `datetime()`: Must be valid ISO 8601 datetime
- `time()`: Must be valid time format (HH:MM:SS)

### Transformations

- `trim()`: Removes leading and trailing whitespace
- `toLowerCase()`: Converts to lowercase
- `toUpperCase()`: Converts to uppercase

## `IntegerSchema` / `DoubleSchema` / `NumberSchema` (Number Schemas)

Schemas for validating numeric values. `IntegerSchema` only accepts `int`,
`DoubleSchema` only accepts `double`, and `NumberSchema` accepts any `num`
(either `int` or `double`). `DoubleSchema` and `NumberSchema` reject non-finite
values by default. See [Number Validation](../core-concepts/validation.mdx#number-constraints).

Each method's parameter type matches the schema's runtime type: `int` for `IntegerSchema`, `double` for `DoubleSchema`, and `num` for `NumberSchema`.

- `min(N limit)`: Minimum value (inclusive)
- `max(N limit)`: Maximum value (inclusive)
- `greaterThan(N limit)`: Must be greater than limit (exclusive)
- `lessThan(N limit)`: Must be less than limit (exclusive)
- `positive()`: Must be greater than 0
- `negative()`: Must be less than 0
- `multipleOf(N factor)`: Must be a multiple of the factor
- `finite()`: Must be finite (`DoubleSchema` and `NumberSchema`; already the default)
- `safe()`: Must be within safe integer range (`IntegerSchema` only)

## `BooleanSchema`

Schema for validating booleans. Validates `true` and `false` values strictly — non-boolean inputs are rejected. For boundary types that arrive as strings (e.g. `"true"`/`"false"`), use a `transform` or `codec` to convert before validation.

## `ListSchema<T>`

Schema for validating arrays. See [List Validation](../core-concepts/validation.mdx#list-constraints).

- `minItems(int min)`: Minimum number of items (alias: `minLength`)
- `maxItems(int max)`: Maximum number of items (alias: `maxLength`)
- `exactLength(int exact)`: Exact number of items (alias: `length`)
- `nonEmpty()`: List must have at least one item (alias: `notEmpty`)
- `unique()`: All items must be unique

## `ObjectSchema`

Schema for validating objects (maps). See [Object Validation](../core-concepts/schemas.mdx#object).

- Constructed using `Ack.object(Map<String, AckSchema> properties, {bool additionalProperties = false})`.
- Use `.pick(List<String> keys)` to create schema with only specified properties.
- Use `.omit(List<String> keys)` to create schema excluding specified properties.
- Use `.extend(Map<String, AckSchema> newProperties)` to add more properties.
- Use `.partial()` to make all properties optional.
- Use `.strict()` to disallow additional properties.
- Use `.passthrough()` to allow additional properties not defined in the schema.
- Use `.merge(ObjectSchema other)` to combine with another object schema.

## `SchemaResult<T>`

Object returned by `safeParse()`. See [Error Handling](../core-concepts/error-handling.mdx).

- `bool isOk`: `true` if validation succeeded.
- `bool isFail`: `true` if validation failed.
- `T? getOrThrow()`: Returns the validated value (which can be `null` for a nullable schema), or throws `AckException` on failure.
- `T? getOrNull()`: Returns the validated value, or `null` on failure.
- `SchemaError getError()`: Returns the validation error; only valid when `isFail` is `true`.
- `T? getOrElse(T? Function() orElse)`: Returns the validated value, or calls `orElse` on failure.
- `SchemaResult<R> map<R>(R Function(T?) transform)`: Maps the successful value to a new result type; propagates failures unchanged.
- `R match<R>({required R Function(T?) onOk, required R Function(SchemaError) onFail})`: Pattern-matches on success or failure.
- `void ifOk(void Function(T?) action)`: Executes `action` only when the result is successful.
- `void ifFail(void Function(SchemaError) action)`: Executes `action` only when the result is a failure.

## `SchemaError` (and subclasses)

Represents a validation failure. See [Error handling](../core-concepts/error-handling.mdx).

- `String message`: Human-readable error message.
- `SchemaContext context`: Context about where the error occurred.

**Subclasses:**
- `SchemaConstraintsError`: One or more constraint violations.
- `SchemaNestedError`: Validation failures in nested objects or arrays.
- `SchemaValidationError`: Custom refinement failures.
- `SchemaEncodeError`: Encode-path failures (non-nullable null, one-way transform, encoder threw, etc.).

## `Constraint<T>`

Base class for custom validation rules. See [Custom validation](../guides/custom-validation.mdx).

- `String constraintKey`: Unique identifier for the constraint.
- `String description`: Human-readable description.
- `Map<String, Object?> toMap()`: Serializes the constraint for debugging.

## `Validator<T>` (mixin)

Validation behavior mixin used with `Constraint<T>`.

- `bool isValid(T value)`: Returns `true` when the value passes validation.
- `String buildMessage(T value)`: Builds the validation failure message.
- `ConstraintError? validate(T value)`: Validates a value and returns an error if invalid.

## Additional schema types

Ack ships with a broad set of schema factories beyond what is listed here.
See [Schema types](../core-concepts/schemas.mdx) for the full catalogue,
including `Ack.date()`, `Ack.literal()`, and list/object combinators.

### `Ack.discriminated(...)`

Schema for polymorphic validation based on a string discriminator property.

- Branch schemas normally omit the discriminator field.
- The boundary payload must still contain the discriminator key.
- If a branch schema includes the discriminator field, it must be
  `Ack.literal(...)` matching the branch key or `Ack.enumString(...)`
  containing it. Broad, transformed, refined, or otherwise restrictive
  discriminator fields are rejected.
- Exported and generated schemas expose each branch discriminator as an exact
  literal.
- Generated subtype `parse()` and `safeParse()` methods validate through the
  union's effective branch.

### `Ack.lazy(...)`

Schema reference for recursive object graphs.

- Created using `Ack.lazy<Boundary, Runtime>(name, builder)`.
- The builder is resolved once and memoized.
- `toJsonSchema()` and `toSchemaModel()` export Draft-7 `definitions` / `$ref`
  entries using the lazy `name`.
- Bare or wrapped lazy schemas cannot be used as discriminated-union branches
  because the branch discriminator must be analyzable at construction time.

## Code generation annotations

Use the [`ack_generator`](https://pub.dev/packages/ack_generator) builder to turn annotations into extension types. After adding the annotations below, run:

```bash
dart run build_runner build --delete-conflicting-outputs
```

### `@AckType()`

**Target**: Schema variables and getters

**Generates**: An extension type wrapper around the existing schema

Annotate a schema variable or getter to generate an extension type wrapper. The schema stays in your source file.

**Supported schema types:**
- `Ack.object({...})` → Object extension types
- Primitives: `Ack.string()`, `Ack.integer()`, `Ack.double()`, `Ack.boolean()`
- Collections: `Ack.list(...)`
- Enums: `Ack.literal()`, `Ack.enumString()`, `Ack.enumValues()`
- Discriminated unions: `Ack.discriminated(...)`

**Unsupported:** `Ack.any()`, `Ack.anyOf()`

For `Ack.discriminated(...)` constraints with `@AckType`, see
[Type-safe Schemas](../core-concepts/typesafe-schemas.mdx#discriminated-schemas).

**Example:**
```dart
@AckType()
final userSchema = Ack.object({
  'name': Ack.string(),
  'email': Ack.string().email(),
});

// Generated:
// - extension type UserType(Map<String, Object?> _data) { ... }
// - The schema variable remains unchanged

// Usage:
final user = UserType.parse({'name': 'Alice', 'email': 'alice@example.com'});
print(user.name);  // Type-safe String access
print(user.email); // Type-safe String access
```

### `EnumSchema<T>`

Schema for validating enum values. Created using `Ack.enumValues(List<T> values)` where `T extends Enum`.

### `AnyOfSchema`

Schema for union types; the value must match one of several schemas. Created using `Ack.anyOf(List<AckSchema> schemas)`.

### `DiscriminatedObjectSchema`

Schema for polymorphic validation based on a discriminator field.

- Created using `Ack.discriminated<T extends Object>(...)` with
  `discriminatorKey` and `schemas`.
- `effectiveBranch(String discriminatorValue)`: Returns the branch schema with
  the discriminator injected as the exact branch literal. Generated subtypes use
  this to validate a specific branch.

### `AckSchemaModel`

Canonical export model for Ack schemas.

- Created by `schema.toSchemaModel()`.
- Represents the boundary/export shape, JSON-compatible defaults, discriminator metadata, target-independent constraints, and export warnings.
- `schema.toSchemaModel().toJsonSchema()` returns the same Draft-7 map as `schema.toJsonSchema()`.
- Adapters that need a JSON map should call `schema.toJsonSchema()`; adapters for non-JSON targets should convert from `AckSchemaModel` rather than traversing `AckSchema` subclasses directly.

### `AnySchema`

Accepts any non-null JSON-safe value without further validation.

- Created by `Ack.any()`.
- Useful for dynamic payloads or pass-through metadata.

### `CodecSchema<Boundary, Runtime>`

Schema that decodes boundary values into runtime values and encodes runtime
values back to the boundary representation. Use `encode` / `safeEncode` for the
reverse direction. See [Codecs](../core-concepts/codecs.mdx).

- `schema.transform<R>(R Function(Runtime) transformer)`: one-way transform
  (parse only; `encode` fails with a one-way error).
- `schema.codec<R>({required R Function(Runtime) decode, required Runtime Function(R) encode, AckSchema<dynamic, R>? output})`:
  bidirectional codec; the optional `output` schema validates the runtime value.
- `Ack.codec<Boundary, InputRuntime, Runtime>({required input, required decode, required encode, output})`:
  builds a codec from an `input` schema.

**Built-in codecs:**

- `Ack.date()` → `CodecSchema<String, DateTime>` (ISO `YYYY-MM-DD` ↔ local-midnight `DateTime`)
- `Ack.datetime()` → `CodecSchema<String, DateTime>` (ISO 8601 ↔ UTC `DateTime`)
- `Ack.uri()` → `CodecSchema<String, Uri>` (absolute URI string ↔ `Uri`)
- `Ack.duration()` → `CodecSchema<int, Duration>` (milliseconds ↔ `Duration`)
- `Ack.enumCodec(List<T> values)` → `CodecSchema<String, T>` (enum `.name` ↔ enum value)

### Optional schemas

Every schema can be marked optional via the `optional({bool value = true})` fluent API.

- `schema.optional()` sets `isOptional` to `true` without wrapping the schema.
- `schema.optional(value: false)` clears the optional flag.
- Optional affects object-field presence only; combine with `.nullable()` to also allow explicit `null`.

*See the [Schema types](../core-concepts/schemas.mdx) guide for detailed usage and examples.*
