> For the complete documentation index, see [llms.txt](https://docs.internetobject.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.internetobject.org/schema-definition-language/advanced-schema-concepts/dynamic-schema.md).

# Open & Dynamic Schemas

By default a schema is **closed**: a record may contain only the declared fields. Adding a `*` marker makes the schema **open**, allowing extra fields beyond those declared.

## Closed by default

Extra values in a record are rejected unless the schema opts in with `*`:

```ruby
~ $schema: { name: string, age: int }
---
~ John, 30                # ✓
~ Alex, 25, extra1        # ✗ additional-values-not-allowed
```

## Allowing extra fields with `*`

Place `*` after the declared fields to accept extras. Positional extras are keyed by index; keyed extras keep their names:

```ruby
~ $schema: { name: string, age: int, * }
---
~ John, 30                       # ✓
~ Alex, 25, Male, cool           # ✓ extras at index 2 and 3
~ { Mia, 28, role: dev }         # ✓ extra keyed field "role"
```

## Typing the extra fields

`*: <type>` constrains every extra field; `*: { <type>, …constraints }` adds constraints:

```ruby
~ $schema: { name: string, *: string }
---
~ { John, role: dev }     # ✓
~ { Alex, code: 123 }     # ✗ not-a-string — extra value must be a string
```

```ruby
~ $schema: { name: string, *: { string, minLen: 4 } }
---
~ { John, dept: Sales }   # ✓
~ { Mia, id: "12" }       # ✗ invalid-min-length — extra is shorter than 4
```

## Dynamic types with anyOf

When a single field must accept more than one type, use `anyOf` (see [Any](/schema-definition-language/data-types/any.md)):

```ruby
test: { any, anyOf: [string, number] }
---
~ One     # ✓
~ 1       # ✓
~ Two     # ✓
```

## When to use curly braces

A top-level schema needs braces only when wrapping a nested object. A nested field with more than one member MUST be enclosed in `{ … }`:

```ruby
# 'address' captures only 'street'; city/state become separate fields — usually not intended
name, age, address: street, city, state, isActive
```

```ruby
# 'address' is a nested object with three members
name, age, address: { street, city, state }, isActive
```

## See Also

* [Internet Object Schema](/schema-definition-language/internet-object-schema.md) · [Any](/schema-definition-language/data-types/any.md)
* [Object (SchemaDef)](/schema-definition-language/data-types/object.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.internetobject.org/schema-definition-language/advanced-schema-concepts/dynamic-schema.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
