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

# Schema references

> Reuse JSON schema definitions across AgentMark prompts with $ref

## Overview

AgentMark supports JSON Schema `$ref` references in prompt schemas. Instead of duplicating the same schema definition across multiple prompts, you can extract shared definitions into `.json` files and reference them with `$ref`. At build time, AgentMark resolves all references and inlines the content.

This keeps schemas DRY: define a schema once and reuse it across many prompts. When you update a referenced schema, every prompt that points to it picks up the change.

Schema references work in both `input_schema` (input validation) and `object_config.schema` (structured output).

## Basic usage

Create a JSON schema file, then reference it from your prompt's frontmatter using `$ref`.

### Schema file

```json schemas/user.json theme={null}
{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "email": { "type": "string", "format": "email" },
    "role": { "type": "string", "enum": ["admin", "member", "viewer"] }
  },
  "required": ["name", "email"]
}
```

### Prompt file with `$ref`

```jsx greet-user.prompt.mdx theme={null}
---
name: greet-user
text_config:
  model_name: openai/gpt-5
input_schema:
  $ref: ./schemas/user.json
---

<System>You are a friendly assistant.</System>
<User>Greet the user: {props.name} ({props.email}), who has the role {props.role}.</User>
```

When AgentMark processes this prompt, it loads `schemas/user.json` and replaces the `$ref` with the full schema content. The result is identical to having written the schema inline.

### Using `$ref` in output schemas

You can also use `$ref` in `object_config.schema` to define the structure of generated objects.

```jsx extract-contact.prompt.mdx theme={null}
---
name: extract-contact
object_config:
  model_name: openai/gpt-5
  schema:
    $ref: ./schemas/user.json
---

<System>Extract contact information from the following text.</System>
<User>{props.text}</User>
```

### Using `$ref` for nested properties

You don't need to replace the entire schema with a `$ref`. You can use `$ref` for individual properties within a larger schema.

```jsx create-order.prompt.mdx theme={null}
---
name: create-order
object_config:
  model_name: openai/gpt-5
  schema:
    type: object
    properties:
      customer:
        $ref: ./schemas/user.json
      items:
        type: array
        items:
          $ref: ./schemas/product.json
      total:
        type: number
    required:
      - customer
      - items
---

<System>Create an order from the customer's request.</System>
<User>{props.request}</User>
```

## JSON pointer fragments

You can reference a specific definition within a schema file using a JSON Pointer fragment (RFC 6901). This is useful when you have a file containing multiple related definitions.

### Definitions file

```json schemas/common.json theme={null}
{
  "$defs": {
    "Address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "zip": { "type": "string" },
        "country": { "type": "string" }
      },
      "required": ["street", "city"]
    },
    "PhoneNumber": {
      "type": "string",
      "pattern": "^\\+[0-9]{1,15}$"
    }
  }
}
```

### Referencing a specific definition

```jsx contact-form.prompt.mdx theme={null}
---
name: contact-form
object_config:
  model_name: openai/gpt-5
  schema:
    type: object
    properties:
      name:
        type: string
      address:
        $ref: ./schemas/common.json#/$defs/Address
      phone:
        $ref: ./schemas/common.json#/$defs/PhoneNumber
---

<System>Extract contact details from the message.</System>
<User>{props.message}</User>
```

The `#/$defs/Address` fragment tells AgentMark to navigate into the JSON object at `$defs` then `Address`, and inline only that portion. The fragment follows standard JSON Pointer syntax, so any nested path works (for example, `#/$defs/contact/email`).

<Note>
  Both `$defs` and `definitions` work with AgentMark since the fragment is just a JSON Pointer path into the file.
</Note>

## Transitive references

Schema files can themselves contain `$ref` entries that point to other files. AgentMark follows the entire chain and inlines everything.

### Example

```json schemas/user.json theme={null}
{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "address": { "$ref": "./address.json" }
  }
}
```

```json schemas/address.json theme={null}
{
  "type": "object",
  "properties": {
    "street": { "type": "string" },
    "city": { "type": "string" },
    "zip": { "type": "string" }
  }
}
```

```jsx user-profile.prompt.mdx theme={null}
---
name: user-profile
text_config:
  model_name: openai/gpt-5
input_schema:
  $ref: ./schemas/user.json
---

<User>Describe the user profile for {props.name}.</User>
```

AgentMark resolves `user.json`, then sees the `$ref` to `address.json` inside it, resolves that too, and produces a fully inlined schema. Transitive references also work with JSON Pointer fragments. A referenced file can use `$ref: ./geo.json#/definitions/Coordinate` and it resolves correctly.

AgentMark supports up to 50 levels of transitive references.

<Note>
  Fragment-only references like `$ref: "#/$defs/Address"` (no file path) are standard JSON Schema internal references. AgentMark preserves these as-is for runtime validation and doesn't attempt to resolve them.
</Note>

## Security constraints

AgentMark enforces security boundaries on `$ref` resolution.

* **Local files only**: AgentMark supports only relative file paths. It doesn't fetch remote URLs like `https://example.com/schema.json`.
* **Project directory boundary**: Resolved paths must stay within the project directory. The content loader rejects path traversal attempts like `../../../etc/passwd`.
* **No absolute paths**: AgentMark rejects absolute paths like `/etc/passwd`.
* **AgentMark drops sibling properties**: When AgentMark resolves a `$ref`, the referenced content replaces the entire object. AgentMark discards any sibling properties next to `$ref` (like `description`). Place additional properties in the referenced schema file instead.

## Error handling

When AgentMark can't resolve a `$ref`, it throws an error prefixed `Schema $ref error: `.

| Error                                                                  | Cause                                               | Fix                                                          |
| ---------------------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------ |
| `Schema $ref error: file not found "<path>" (referenced from "<dir>")` | Referenced file doesn't exist                       | Check the file path is correct and relative to the prompt    |
| `Schema $ref error: "<path>" is not valid JSON`                        | File contains malformed JSON                        | Validate with a JSON linter                                  |
| `Schema $ref error: circular reference detected: A -> B -> A`          | Two or more schemas reference each other in a cycle | Break the cycle by inlining the shared portion               |
| `Schema $ref error: maximum resolution depth (50) exceeded`            | Reference chain is deeper than 50 levels            | Simplify the schema hierarchy                                |
| `Schema $ref error: JSON pointer "<pointer>" not found in "<path>"`    | Fragment path doesn't match any key in the file     | Check the `#/...` fragment matches the target file structure |

<div className="mt-8 rounded-lg bg-blue-50 p-6 dark:bg-blue-900/30">
  <h3 className="font-semibold mb-3">Have questions?</h3>
  <p className="mb-4">Reach out any time:</p>

  <ul>
    <li>
      Email the team at <a href="mailto:hello@agentmark.co" className="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-200">[hello@agentmark.co](mailto:hello@agentmark.co)</a> for support
    </li>

    <li>
      Schedule an <a href="https://cal.com/ryan-randall/enterprise" className="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-200">Enterprise Demo</a> to learn about AgentMark's business solutions
    </li>
  </ul>
</div>
