Skip to main content
The Schema API provides access to the content type registry. It lets you introspect the types defined in your project and sync schema changes from the CLI.

List Types

/api/v1/schema
Returns all content types registered in the current project and environment, including resolved field metadata.
Scope required: schema:read Example request:
curl "https://cms.example.com/api/v1/schema" \
  -H "X-MDCMS-Project: marketing-site" \
  -H "X-MDCMS-Environment: production" \
  -H "Authorization: Bearer mdcms_key_live_abc123"
Response:
{
  "data": {
    "types": [
      {
        "name": "Author",
        "directory": "content/authors",
        "localized": false,
        "fields": {
          "name": {
            "kind": "string",
            "required": true,
            "nullable": false,
            "default": null,
            "reference": null,
            "checks": [{ "type": "min", "value": 1 }]
          },
          "bio": {
            "kind": "string",
            "required": false,
            "nullable": false,
            "default": null,
            "reference": null,
            "checks": []
          },
          "website": {
            "kind": "string",
            "required": false,
            "nullable": false,
            "default": null,
            "reference": null,
            "checks": [{ "type": "url" }]
          }
        }
      },
      {
        "name": "BlogPost",
        "directory": "content/blog",
        "localized": true,
        "fields": {
          "title": {
            "kind": "string",
            "required": true,
            "nullable": false,
            "default": null,
            "reference": null,
            "checks": [
              { "type": "min", "value": 1 },
              { "type": "max", "value": 200 }
            ]
          },
          "slug": {
            "kind": "string",
            "required": true,
            "nullable": false,
            "default": null,
            "reference": null,
            "checks": [{ "type": "regex", "value": "^[a-z0-9-]+$" }]
          },
          "author": {
            "kind": "reference",
            "required": true,
            "nullable": false,
            "default": null,
            "reference": {
              "targetType": "Author"
            },
            "checks": []
          },
          "publishedAt": {
            "kind": "date",
            "required": true,
            "nullable": false,
            "default": null,
            "reference": null,
            "checks": []
          },
          "tags": {
            "kind": "array",
            "required": false,
            "nullable": false,
            "default": [],
            "reference": null,
            "checks": [],
            "items": {
              "kind": "string",
              "checks": []
            }
          }
        }
      }
    ],
    "schemaHash": "sha256_abc123def456789"
  }
}

Field Metadata

Each field in the response includes the following properties:
PropertyTypeDescription
kindstringThe field’s data type: string, number, boolean, date, array, object, reference, enum.
requiredbooleanWhether the field must be present in frontmatter.
nullablebooleanWhether the field accepts null as a value.
defaultanyDefault value applied when the field is omitted. null means no default.
referenceobject | nullFor reference fields, contains targetType. null for non-reference fields.
checksarrayValidation constraints derived from the Zod schema (e.g., min, max, regex, url, email).

Get Type

/api/v1/schema/{type}
Returns the full schema definition for a single content type.
Scope required: schema:read

Path Parameters

type
string
required
The content type name (e.g., BlogPost).
Example request:
curl "https://cms.example.com/api/v1/schema/BlogPost" \
  -H "X-MDCMS-Project: marketing-site" \
  -H "X-MDCMS-Environment: production" \
  -H "Authorization: Bearer mdcms_key_live_abc123"
Response:
{
  "data": {
    "name": "BlogPost",
    "directory": "content/blog",
    "localized": true,
    "fields": {
      "title": {
        "kind": "string",
        "required": true,
        "nullable": false,
        "default": null,
        "reference": null,
        "checks": [
          { "type": "min", "value": 1 },
          { "type": "max", "value": 200 }
        ]
      },
      "slug": {
        "kind": "string",
        "required": true,
        "nullable": false,
        "default": null,
        "reference": null,
        "checks": [{ "type": "regex", "value": "^[a-z0-9-]+$" }]
      },
      "author": {
        "kind": "reference",
        "required": true,
        "nullable": false,
        "default": null,
        "reference": {
          "targetType": "Author"
        },
        "checks": []
      },
      "publishedAt": {
        "kind": "date",
        "required": true,
        "nullable": false,
        "default": null,
        "reference": null,
        "checks": []
      },
      "tags": {
        "kind": "array",
        "required": false,
        "nullable": false,
        "default": [],
        "reference": null,
        "checks": [],
        "items": {
          "kind": "string",
          "checks": []
        }
      }
    },
    "schemaHash": "sha256_abc123def456789"
  }
}
Error cases:
Error CodeCause
SCHEMA_NOT_FOUNDThe requested type name does not exist in the schema registry.

Sync Schema

/api/v1/schema/sync
Push the current schema definition to the server. This is the endpoint called by mdcms schema sync. The operation is idempotent — syncing the same schema twice produces no changes.
Scope required: schema:write

Request Body

rawConfigSnapshot
object
required
The raw configuration object from mdcms.config.ts, serialized as JSON. This is stored for audit and debugging purposes.
resolvedSchema
object
required
The fully resolved schema with all field metadata, environment overlays applied, and references validated. This is what the server uses for content validation.
schemaHash
string
required
A deterministic hash of the resolved schema. Used by content write endpoints to verify client-server schema consistency.
Example request:
curl -X PUT "https://cms.example.com/api/v1/schema/sync" \
  -H "Content-Type: application/json" \
  -H "X-MDCMS-Project: marketing-site" \
  -H "X-MDCMS-Environment: production" \
  -H "X-MDCMS-CSRF-Token: csrf_token_value" \
  -H "Authorization: Bearer mdcms_key_live_abc123" \
  -d '{
    "rawConfigSnapshot": {
      "project": "marketing-site",
      "types": ["Author", "BlogPost"]
    },
    "resolvedSchema": {
      "types": [
        {
          "name": "Author",
          "directory": "content/authors",
          "localized": false,
          "fields": {
            "name": { "kind": "string", "required": true, "nullable": false, "default": null, "reference": null, "checks": [{ "type": "min", "value": 1 }] }
          }
        },
        {
          "name": "BlogPost",
          "directory": "content/blog",
          "localized": true,
          "fields": {
            "title": { "kind": "string", "required": true, "nullable": false, "default": null, "reference": null, "checks": [{ "type": "min", "value": 1 }, { "type": "max", "value": 200 }] },
            "slug": { "kind": "string", "required": true, "nullable": false, "default": null, "reference": null, "checks": [{ "type": "regex", "value": "^[a-z0-9-]+$" }] },
            "author": { "kind": "reference", "required": true, "nullable": false, "default": null, "reference": { "targetType": "Author" }, "checks": [] },
            "publishedAt": { "kind": "date", "required": true, "nullable": false, "default": null, "reference": null, "checks": [] },
            "tags": { "kind": "array", "required": false, "nullable": false, "default": [], "reference": null, "checks": [], "items": { "kind": "string", "checks": [] } }
          }
        }
      ]
    },
    "schemaHash": "sha256_abc123def456789"
  }'
Response:
{
  "data": {
    "synced": true,
    "schemaHash": "sha256_abc123def456789",
    "typesCount": 2,
    "types": ["Author", "BlogPost"],
    "syncedAt": "2026-01-20T10:00:00.000Z",
    "syncedBy": "880e8400-e29b-41d4-a716-446655440002"
  }
}
In practice, you should never call this endpoint directly. Use mdcms schema sync from the CLI, which reads your mdcms.config.ts, resolves the schema, computes the hash, and sends the request.
Schema sync does not perform destructive migrations. If you remove a field from the schema, existing documents that contain that field are not modified. The field simply stops being validated and stops appearing in Studio forms.