> ## Documentation Index
> Fetch the complete documentation index at: https://docs.attio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Form schema

> Defines the shape of your form data

```js theme={"system"}
import {Forms} from "attio/client"
```

The schema is formed using the [builder pattern](https://howtodoinjava.com/design-patterns/creational/builder-pattern-in-java/). Objects can be nested arbitrarily deep.

## Example

```js theme={"system"}
const schema = {
  name: Forms.string(),
  note: Forms.string().multiline(),
  nickname: Forms.string().optional(),
  age: Forms.number().min(18),
  numTokens: Forms.number().max(100),
  phoneNumbers: Forms.array(Forms.string()),
  addresses: Forms.array({
    street: Forms.string(),
    city: Forms.string(),
  }),
  meetingAt: Forms.dateTime()
    .min(new Date("2025-01-01"), {message: "Meeting must be on or after Jan 1, 2025"})
    .max(new Date("2025-12-31"), {message: "Meeting must be on or before Dec 31, 2025"}),
  dateOfBirth: Forms.plainDate().optional(),
  company: Forms.attioRecord().object({slug: "companies"}),
}
```

The allowed `FormValue`s are:

## `Forms.string()`

A string value. Required by default.

### Mutators

`.default(value : string)`

Sets a default value to return when no value is entered by the user.

<Warning>
  This is ***NOT*** the same as an “initial value”, which should be passed to the
  [`useForm()`](./use-form) hook.
</Warning>

`.multiline()`

Will cause the string input to be multiline.

<Info>
  A `<textarea />` rather than an `<input type="text" />` in DOM-speak
</Info>

`.url(options?: { protocol: RegExp; message?: string})`

Validates that the string is a valid URL with an allowed protocol (default http/https) and a valid top-level domain. You can override the allowed protocol via `options.protocol`.

`.optional()`

By default, strings are required. This will change that to let `null`, `undefined`, and `""` pass validation.

## `Forms.number()`

A numeric value. Required by default.

### Mutators

`.default(value : number)`

Sets a default value to return when no value is entered by the user.

<Warning>
  This is ***NOT*** the same as an “initial value”, which should be passed to the
  [`useForm()`](./use-form) hook.
</Warning>

`.optional()`

By default, numbers are required. This will change that to let `null` and `undefined` pass validation.

`.min(min: number)`

Provide a minimum value. Validation will fail if the user inputs number `< min`.

`.max(max: number)`

Provide a maximum value. Validation will fail if the user inputs number `> max`.

## `Forms.array(FormValue | Record<string, FormValue>)`

An array of other form values or objects of form values.

<Info>They are referenced with a `name` prop like `"addresses[0].street"`.</Info>

### Mutators

`.optional()`

By default, arrays are required. This will change that to let `undefined` pass validation.

## `Forms.dateTime()`

A date and time value. Required by default.

### Mutators

`.default(value: Date)`

Sets a default value to return when no value is entered by the user.

<Warning>
  This is ***NOT*** the same as an “initial value,” which should be passed to the
  [`useForm()`](./use-form) hook.
</Warning>

`.optional()`

By default, dateTimes are required. This changes the behavior to allow `undefined` to pass validation.

`.min(date: Date, options?: { message?: string })`

Sets a minimum date. Validation will fail if the user inputs a date earlier than the given date.\
You can override the default error message with `options.message`.

`.max(date: Date, options?: { message?: string })`

Sets a maximum date. Validation will fail if the user inputs a date later than the given date.\
You can override the default error message with `options.message`.

## `Forms.plainDate()`

A date string in ISO 8601 format (YYYY-MM-DD). Required by default.

### Mutators

`.default(value: string)`

Sets a default value to return when no value is entered by the user.

<Warning>
  This is ***NOT*** the same as an “initial value,” which should be passed to the
  [`useForm()`](./use-form) hook.
</Warning>

`.optional()`

By default, plainDates are required. This changes the behavior to allow `undefined` to pass validation.

## `Forms.attioRecord()`

A Attio record. Required by default.

### Mutators

`.default(value: AttioRecord)`

Sets a default value to return when no value is entered by the user.

<Warning>
  This is ***NOT*** the same as an “initial value,” which should be passed to the
  [`useForm()`](./use-form) hook.
</Warning>

`.optional()`

By default, attioRecords are required. This changes the behavior to allow `undefined` to pass validation.

`.object(config: { slug: ObjectSlug | Array<ObjectSlug> })`

Limits which object types can be selected. Accepts either a single object slug via `{ slug: "people" }` or an array of object slugs via `{ slug: ["people", "companies"] }`. Valid object slugs include `"people"`, `"companies"`, `"deals"`, `"users"`, or any custom object slug.
Validation will fail if the user selects a record from an object type not included in the allowed list.
