Skip to main content
The $id keyword identifies a schema or subschema as a distinct schema resource and establishes the base IRI for resolving relative IRI references within that resource.

Syntax

$id
string
required
A string representing a valid IRI reference without a fragment. When resolved against the current base IRI, it becomes the identifier for the schema resource.

Purpose

The $id keyword serves multiple critical functions:
  1. Schema Identification: Provides a unique identifier for the schema resource
  2. Base IRI Establishment: Sets the base IRI for resolving relative references in the schema
  3. Reference Target: Allows other schemas to reference this schema by IRI
  4. Resource Boundary: Defines embedded schema resources within a document

Usage

Root Schema Identification

The root schema of a JSON Schema document SHOULD contain an $id with an absolute IRI (containing a scheme, but no fragment).
{
  "$id": "https://example.com/schemas/product.json",
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "price": { "type": "number" }
  }
}

Embedded Resources

When an $id appears in a subschema, it creates a new embedded schema resource with its own identifier:
{
  "$id": "https://example.com/schemas/main.json",
  "type": "object",
  "properties": {
    "address": {
      "$id": "https://example.com/schemas/address.json",
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" }
      }
    }
  }
}
The embedded address schema can be referenced by its IRI: https://example.com/schemas/address.json

Relative IRI References

$id can use relative IRI references, which are resolved against the current base IRI:
{
  "$id": "https://example.com/schemas/root.json",
  "$defs": {
    "address": {
      "$id": "address.json",
      "type": "object"
    },
    "contact": {
      "$id": "types/contact.json",
      "type": "object"
    }
  }
}
Resolved IRIs:
  • address.jsonhttps://example.com/schemas/address.json
  • types/contact.jsonhttps://example.com/schemas/types/contact.json

IRI Resolution

Base IRI Determination

The base IRI for resolving $id values is determined by:
  1. Explicit $id in parent: If a parent schema has $id, it becomes the base IRI
  2. Document retrieval location: The IRI from which the document was retrieved
  3. Implementation default: Implementation-specific default base IRI

Resolving the $id Value

When resolved against the base IRI, the $id value becomes:
  • The canonical identifier for the schema resource
  • The new base IRI for any nested schemas or references
{
  "$id": "https://example.com/foo",
  "items": {
    "$id": "https://example.com/bar",
    "additionalProperties": {}
  }
}
Base IRIs:
  • Root schema: https://example.com/foo
  • Embedded items schema: https://example.com/bar
  • additionalProperties schema: https://example.com/bar (inherits from parent)

Examples

Schema with References

{
  "$id": "https://example.com/root.json",
  "type": "array",
  "items": { "$ref": "#item" },
  "$defs": {
    "single": {
      "$anchor": "item",
      "type": "object",
      "additionalProperties": { "$ref": "other.json" }
    }
  }
}
  • #item resolves to https://example.com/root.json#item
  • other.json resolves to https://example.com/other.json

Network-Addressable vs Non-Addressable IRIs

{
  "$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f",
  "type": "string"
}
The $id is an identifier, not necessarily a network locator. A schema need not be downloadable from its canonical IRI. URN-based identifiers are valid and useful for schemas not intended for network retrieval.

Important Notes

Empty IRI Fragment

An $id consisting of an empty IRI will result in the embedded resource having the same IRI as its parent, which SHOULD be considered an error.
{
  "$id": "https://example.com/main.json",
  "$defs": {
    "bad": {
      "$id": "",  // Creates duplicate IRI - avoid this!
      "type": "string"
    }
  }
}

Duplicate Schema Identifiers

When multiple schemas attempt to identify as the same IRI through $id, $anchor, or other mechanisms, implementations SHOULD raise an error. The result is otherwise undefined and not interoperable.

Fragment Identifiers

The $id value MUST NOT contain a fragment identifier:
// Invalid - contains fragment
{ "$id": "https://example.com/schema.json#fragment" }

// Valid - no fragment
{ "$id": "https://example.com/schema.json" }
Use $anchor or $dynamicAnchor to create fragment identifiers within a schema resource.
  • $schema - Declares the schema dialect
  • $ref - References schemas by IRI
  • $anchor - Creates plain name fragment identifiers
  • $defs - Common location for reusable schemas

Build docs developers (and LLMs) love