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

# Genson

> Infer JSON Schema from JSON instances using Genson in Python.

[Genson](https://github.com/wolverdude/GenSON) is a Python library that builds a JSON Schema by observing JSON instances. Feed it one or more examples and it produces a schema that accepts all of them.

Genson includes a top-level `"$schema"` field in its default output. It is omitted from the examples below for readability.

## Install

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
pip install genson
```

## Basic usage

<CodeGroup>
  ```python Genson theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  from genson import SchemaBuilder

  builder = SchemaBuilder()
  builder.add_object({
      "name": "Alice Johnson",
      "email": "alice@acme.com",
      "role": "Product Manager"
  })

  print(builder.to_json(indent=2))
  ```

  ```json JSON Schema theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "type": "object",
    "properties": {
      "name": { "type": "string" },
      "email": { "type": "string" },
      "role": { "type": "string" }
    },
    "required": ["email", "name", "role"]
  }
  ```
</CodeGroup>

Genson infers types from values and marks all observed fields as required. Note that Genson sorts `required` alphabetically and does not add `additionalProperties: false`; you should add that manually.

## Multiple instances

Genson's strength is incremental learning. Feed it several examples and it merges them, detecting which fields are always present (required) and which appear only sometimes (optional):

<CodeGroup>
  ```python Genson theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  builder = SchemaBuilder()
  builder.add_object({"name": "Alice", "email": "alice@acme.com", "phone": "+1-555-0100"})
  builder.add_object({"name": "Bob", "email": "bob@acme.com"})
  builder.add_object({"name": "Carol", "email": "carol@acme.com", "phone": "+1-555-0102"})
  ```

  ```json JSON Schema theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "type": "object",
    "properties": {
      "name": { "type": "string" },
      "email": { "type": "string" },
      "phone": { "type": "string" }
    },
    "required": ["email", "name"]
  }
  ```
</CodeGroup>

Since `phone` is missing from the second example, it becomes optional while `name` and `email` stay required.

## Nested objects

Genson handles nested structures, inferring a full sub-schema for each nested object:

<CodeGroup>
  ```python Genson theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  builder = SchemaBuilder()
  builder.add_object({
      "name": "Alice",
      "address": {
          "street": "123 Main St",
          "city": "Springfield",
          "country": "US"
      }
  })
  ```

  ```json JSON Schema theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "type": "object",
    "properties": {
      "name": { "type": "string" },
      "address": {
        "type": "object",
        "properties": {
          "street": { "type": "string" },
          "city": { "type": "string" },
          "country": { "type": "string" }
        },
        "required": ["city", "country", "street"]
      }
    },
    "required": ["address", "name"]
  }
  ```
</CodeGroup>

Unlike Pydantic or Quicktype, Genson inlines nested objects rather than extracting them into `$defs`.

## Arrays

Genson infers array item types from the elements it sees:

<CodeGroup>
  ```python Genson theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  builder = SchemaBuilder()
  builder.add_object({
      "question": "What is your favorite color?",
      "options": ["red", "green", "blue"],
      "tags": ["survey", "color"]
  })
  ```

  ```json JSON Schema theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "type": "object",
    "properties": {
      "question": { "type": "string" },
      "options": {
        "type": "array",
        "items": { "type": "string" }
      },
      "tags": {
        "type": "array",
        "items": { "type": "string" }
      }
    },
    "required": ["options", "question", "tags"]
  }
  ```
</CodeGroup>

Genson does not add `minItems` or `maxItems`; add those manually. See [Bounded Arrays](/json-schema/bounded-arrays).

## Arrays of objects

When arrays contain objects, Genson infers the item schema by merging all observed elements:

<CodeGroup>
  ```python Genson theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  builder = SchemaBuilder()
  builder.add_object({
      "contacts": [
          {"name": "Alice", "email": "alice@acme.com"},
          {"name": "Bob", "email": "bob@acme.com"}
      ]
  })
  ```

  ```json JSON Schema theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "type": "object",
    "properties": {
      "contacts": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "name": { "type": "string" },
            "email": { "type": "string" }
          },
          "required": ["email", "name"]
        }
      }
    },
    "required": ["contacts"]
  }
  ```
</CodeGroup>

## Mixed types

When the same field has different types across samples, Genson produces a type union:

<CodeGroup>
  ```python Genson theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  builder = SchemaBuilder()
  builder.add_object({"value": 42})
  builder.add_object({"value": "hello"})
  ```

  ```json JSON Schema theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "type": "object",
    "properties": {
      "value": {
        "type": ["integer", "string"]
      }
    },
    "required": ["value"]
  }
  ```
</CodeGroup>

## Seeding with an existing schema

You can start from a hand-written schema and let Genson extend it with fields observed in data. Constraints from the seed schema (like `enum`) are preserved:

<CodeGroup>
  ```python Genson theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  builder = SchemaBuilder()
  builder.add_schema({
      "type": "object",
      "properties": {
          "category": {
              "type": "string",
              "enum": ["billing", "account", "bug"]
          }
      },
      "required": ["category"]
  })
  builder.add_object({"category": "billing", "summary": "Can't login"})
  ```

  ```json JSON Schema theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "type": "object",
    "properties": {
      "category": {
        "type": "string",
        "enum": ["billing", "account", "bug"]
      },
      "summary": { "type": "string" }
    },
    "required": ["category"]
  }
  ```
</CodeGroup>

The `enum` constraint on `category` is preserved from the seed. `summary` is added to `properties` but not to `required` since it was not in the seed's `required` list.

## Limitations

Genson infers structure and types but does not add semantic constraints. The generated schema will not include:

* `enum` values (unless seeded)
* `minLength`, `maxLength`, or `pattern` for strings
* `minItems`, `maxItems` for arrays
* `additionalProperties: false` on objects
* `description` on fields or the schema

The output is a starting point. Tighten it by adding constraints manually or follow [Improve your schema](/json-schema/improve-your-schema).
