Skip to main content

Schema Registry API

Qarion exposes three schema-registry surfaces:

  • Catalog Schema Registry: reusable, space-scoped schema entries that products can reference instead of storing inline schema copies.
  • Event Contract Registry: governed event contracts, versions, validation, compatibility checks, repository sync, and external schema registry connections.
  • Runtime Event Registry: read-only access to approved, immutable Event Contract versions and schemas.

All endpoints are served under /api/v1.0. Paths below omit that prefix.

Endpoint Overview

Catalog Schema Entries

MethodEndpointPurpose
GET/catalog/spaces/{slug}/schema-registryList reusable schema entries in a space.
POST/catalog/spaces/{slug}/schema-registryCreate a schema entry.
GET/catalog/spaces/{slug}/schema-registry/{schema_id}Get one schema entry.
PATCH/catalog/spaces/{slug}/schema-registry/{schema_id}Update a schema entry.
DELETE/catalog/spaces/{slug}/schema-registry/{schema_id}Delete a schema entry.

Event Contracts

MethodEndpointPurpose
GET/spaces/{slug}/event-contractsList Event Contracts with filters.
POST/spaces/{slug}/event-contractsCreate an Event Contract identity.
GET/spaces/{slug}/event-contracts/{contract_id}Get contract detail with versions.
PATCH/spaces/{slug}/event-contracts/{contract_id}Update contract metadata.
POST/spaces/{slug}/event-contracts/repository-syncImport contract files from repository content.
GET/spaces/{slug}/event-contracts/{contract_id}/versionsList contract versions.
POST/spaces/{slug}/event-contracts/{contract_id}/versionsCreate a draft contract version.
PATCH/spaces/{slug}/event-contracts/{contract_id}/versions/{version_id}Update a draft version.
POST/spaces/{slug}/event-contracts/{contract_id}/versions/{version_id}/validateValidate one version.
POST/spaces/{slug}/event-contracts/{contract_id}/versions/{version_id}/compatibility-checkCompare one version to the approved baseline.
POST/spaces/{slug}/event-contracts/{contract_id}/versions/{version_id}/publishPublish an approved version.
GET/spaces/{slug}/event-contracts/{contract_id}/exportExport the latest contract in a target format.
POST/spaces/{slug}/event-contracts/{contract_id}/resolve-conflictResolve a Git/Qarion conflict.

External Schema Registry Connections

MethodEndpointPurpose
GET/spaces/{slug}/event-contracts/registry-connectionsList external registry connections.
POST/spaces/{slug}/event-contracts/registry-connectionsCreate a registry connection.
PATCH/spaces/{slug}/event-contracts/registry-connections/{connection_id}Update a registry connection.
DELETE/spaces/{slug}/event-contracts/registry-connections/{connection_id}Delete a registry connection.
POST/spaces/{slug}/event-contracts/registry-connections/{connection_id}/testTest a registry connection.
GET/spaces/{slug}/event-contracts/registry-connections/{connection_id}/remote-referencesBrowse remote subjects, artifacts, or Iglu schemas.
POST/spaces/{slug}/event-contracts/registry-connections/{connection_id}/pull-previewFetch a remote schema without creating a local version.
POST/spaces/{slug}/event-contracts/registry-connections/{connection_id}/pull-importImport a remote schema as a local Event Contract version.

Registry Bindings

MethodEndpointPurpose
GET/spaces/{slug}/event-contracts/{contract_id}/registry-bindingsList bindings for a contract.
POST/spaces/{slug}/event-contracts/{contract_id}/registry-bindingsBind a contract to a remote registry identity.
PATCH/spaces/{slug}/event-contracts/{contract_id}/registry-bindings/{binding_id}Update a binding.
DELETE/spaces/{slug}/event-contracts/{contract_id}/registry-bindings/{binding_id}Delete a binding.
POST/spaces/{slug}/event-contracts/{contract_id}/registry-bindings/{binding_id}/pushPush an approved local version to the remote registry.
POST/spaces/{slug}/event-contracts/{contract_id}/registry-bindings/{binding_id}/compatibility-syncRead or set remote compatibility mode.

Runtime Registry

MethodEndpointPurpose
GET/registry/events/{event_name}/latest-approvedResolve the latest approved local Event Contract version.
GET/registry/events/{event_name}/versions/{version_value}Resolve a specific approved immutable version.
GET/registry/events/{event_name}/schemaReturn the latest approved schema document only.
GET/registry/iglu/schemas/{vendor}/{name}/{schema_format}/{version_value}Return an Iglu-compatible schema response.

Permissions And Feature Gates

Event Contract routes require the event_contracts.enabled feature. They use the event_contract resource with these actions:

ActionUsed by
viewLists, details, version lists, exports, remote-reference browsing.
createCreating contracts and importing a remote schema without an existing contract_id.
editUpdating contracts and versions, validation, compatibility checks, and importing into an existing contract.
publishPublishing a version.
syncRepository sync, registry connection CRUD/test, pull preview/import, binding CRUD, push, and compatibility sync.
resolve_conflictResolving repository sync conflicts.

Mutating registry connection and binding sync routes require a non-impersonated user. Runtime registry endpoints return only approved, non-conflicted local Event Contract versions; external registry state is evidence for sync UX, not the runtime source of truth.

Catalog Schema Entries

Catalog schema entries are reusable schema definitions scoped to a space. They are used by product details such as media manifest schema pickers and are also updated when Data Contract schema definitions are changed through contract services.

Schema Entry Shape

{
"id": "1c61ec14-8d8c-4e0d-b3c7-a1afeb52458d",
"space_id": "82d7d96a-b7f5-4d19-8bb9-42127bb6399c",
"name": "Customer Event Manifest",
"slug": "customer-event-manifest",
"description": "Reusable schema for customer event manifests.",
"version": 1,
"schema_fields": [
{
"name": "customer_id",
"type": "string",
"description": "Stable customer identifier.",
"required": true,
"enum_values": null
}
],
"raw_json_schema": null,
"created_at": "2026-06-26T09:15:22.533000Z",
"updated_at": "2026-06-26T09:15:22.533000Z"
}

Field types accepted by schema_fields[].type include string, number, integer, boolean, array, object, date, and enum. Use enum_values only when type is enum.

Create Schema Entry

POST /catalog/spaces/{slug}/schema-registry
Content-Type: application/json
{
"name": "Customer Event Manifest",
"description": "Reusable schema for customer event manifests.",
"schema_fields": [
{
"name": "event_type",
"type": "enum",
"required": true,
"enum_values": ["created", "updated", "deleted"]
}
],
"raw_json_schema": {
"type": "object",
"required": ["event_type"]
}
}

If slug is omitted, the service generates one from name. Updates are partial. If a PATCH omits version, the service increments the stored version. If you send version, that value is stored as supplied.

Event Contract Registry

Event Contracts model governed event schema identities and their versioned documents.

Contract Identity

Create a contract with either event_name or the structured domain/entity/action identity parts.

POST /spaces/{slug}/event-contracts
Content-Type: application/json
{
"event_name": "orders.order.created",
"event_kind": "business",
"lifecycle_status": "draft",
"description": "Published when a customer order is accepted.",
"producer_product_id": "7da5fb7e-507a-4324-af2b-ffcb9d40e6f0",
"source_system_id": "72637167-f769-4ae3-b709-4560de2ee402",
"external_bindings": {
"kafka": {
"topic": "orders.order.created"
}
}
}

List filters include:

Query parameterMeaning
statusFilter by contract lifecycle status.
event_kindFilter by event kind.
producerFilter by producer text.
source_systemFilter by source system UUID.
data_stream_productFilter by data stream product UUID or slug. Unknown slugs return an empty list.
formatFilter by version schema format.
searchText search.

Versions

Create a draft version with schema_document or raw_document.

POST /spaces/{slug}/event-contracts/{contract_id}/versions
Content-Type: application/json
{
"version": "1.0.0",
"schema_format": "avro",
"schema_document": {
"type": "record",
"name": "OrderCreated",
"namespace": "com.example.orders",
"fields": [
{ "name": "order_id", "type": "string" }
]
},
"source_origin": "qarion"
}

Supported version formats are qarion, json_schema, iglu, asyncapi, avro, and protobuf. Draft versions can be updated. Published versions become approved runtime candidates.

Validation And Compatibility

POST /spaces/{slug}/event-contracts/{contract_id}/versions/{version_id}/validate
POST /spaces/{slug}/event-contracts/{contract_id}/versions/{version_id}/compatibility-check

Both endpoints return:

{
"passed": true,
"change_kind": "compatible",
"baseline_version_id": "c7a96891-092f-4d37-979b-246f42c5f449",
"checks": [
{
"guardrail": "event_contract.compatibility.format",
"passed": true,
"message": "Schema format is compatible with the approved baseline.",
"severity": "info"
}
]
}

compatibility-check compares against the latest approved version when one is available. Publish is blocked while the contract is in a conflicted sync state.

Publish And Export

POST /spaces/{slug}/event-contracts/{contract_id}/versions/{version_id}/publish
GET /spaces/{slug}/event-contracts/{contract_id}/export?format=avro

Publish accepts optional approval_metadata. Export returns event_name, version, format, content_type, serialized content, and checksum.

Repository Sync And Conflicts

POST /spaces/{slug}/event-contracts/repository-sync
Content-Type: application/json
{
"files": [
{
"path": "schemas/events/orders.order.created.yaml",
"content": "kind: event_contract\nmetadata:\n name: orders.order.created\n",
"commit_sha": "7c0dfb7"
}
]
}

Response counters include created, updated, conflicted, skipped, contracts, and errors. Resolve a conflict by selecting a version or sending a merged draft:

POST /spaces/{slug}/event-contracts/{contract_id}/resolve-conflict
Content-Type: application/json
{
"selected_version_id": "80f40209-85f8-4f3b-8018-b63952d8b6e8",
"notes": "Use the repository-authored version."
}

External Registry Connections

External connections support Confluent Schema Registry, Apicurio Registry, and Iglu Server.

ProviderProvider valueRemote identityPush formatsCompatibility sync
Confluent Schema Registryconfluentsubjectjson_schema, avro, protobufYes
Apicurio Registryapicurioartifact or compatible subjectjson_schema, avro, protobuf, asyncapiYes
Iglu ServerigluigluigluNo Confluent-style mode

Create Connection

POST /spaces/{slug}/event-contracts/registry-connections
Content-Type: application/json
{
"name": "Confluent production",
"provider": "confluent",
"base_url": "https://schema-registry.example.com",
"auth_mode": "api_key",
"source_system_id": "72637167-f769-4ae3-b709-4560de2ee402",
"credential_id": "44a93342-4115-42e4-a390-e44b1fb667b1",
"connection_config": {
"api_key_header": "Authorization",
"api_key_prefix": "Bearer"
},
"default_subject_strategy": "topic_name",
"default_compatibility_mode": "BACKWARD",
"default_sync_direction": "manual",
"is_active": true
}

Supported auth_mode values are none, api_key, bearer, and basic. Authenticated connections require an active credential. Secrets are stored in the credential store, not on the registry connection. Responses include has_credential and redacted connection_config.

Connections are unique by space_id and name. base_url must be a valid external HTTP(S) URL and is stored without a trailing slash.

Connection Response

{
"id": "f74652cc-e90b-4678-a845-67438beb76d3",
"space_id": "82d7d96a-b7f5-4d19-8bb9-42127bb6399c",
"name": "Confluent production",
"provider": "confluent",
"base_url": "https://schema-registry.example.com",
"auth_mode": "api_key",
"source_system_id": "72637167-f769-4ae3-b709-4560de2ee402",
"credential_id": "44a93342-4115-42e4-a390-e44b1fb667b1",
"has_credential": true,
"connection_config": {
"api_key_header": "Authorization",
"api_key_prefix": "Bearer"
},
"default_subject_strategy": "topic_name",
"default_compatibility_mode": "BACKWARD",
"default_sync_direction": "manual",
"is_active": true,
"status": "untested",
"status_details": null,
"last_tested_at": null,
"last_synced_at": null,
"created_at": "2026-06-26T10:10:00Z",
"updated_at": "2026-06-26T10:10:00Z"
}

Test And Browse

POST /spaces/{slug}/event-contracts/registry-connections/{connection_id}/test
GET /spaces/{slug}/event-contracts/registry-connections/{connection_id}/remote-references?search=orders&limit=50

remote-references accepts limit from 1 to 200 and returns provider references such as subjects, Apicurio artifacts, or Iglu schema coordinates.

Pull From External Registry

Preview a remote schema without creating local state:

POST /spaces/{slug}/event-contracts/registry-connections/{connection_id}/pull-preview
Content-Type: application/json
{
"remote_reference_type": "subject",
"subject": "orders.order.created-value",
"version": "latest"
}

Import the same remote schema as a local draft Event Contract version:

POST /spaces/{slug}/event-contracts/registry-connections/{connection_id}/pull-import
Content-Type: application/json
{
"remote_reference_type": "subject",
"subject": "orders.order.created-value",
"version": "latest",
"contract_id": "13db74fd-e99f-4929-aad7-32c330c707f6",
"local_version": "remote-2026-06-26",
"create_binding": true
}

If contract_id is omitted, the service creates a new Event Contract using event_name or a name inferred from the remote schema. Imported versions use source_origin: "schema_registry". When create_binding is true, Qarion also creates a registry binding from the remote identity when possible.

For Apicurio, use remote_reference_type: "artifact" with artifact_group and artifact_id. For Iglu, use remote_reference_type: "iglu" with iglu_vendor, iglu_name, iglu_format, and iglu_version.

Registry Bindings

Bindings link one Event Contract to one remote registry identity. They are unique by connection_id, resolved_identity, and binding_role.

Create Binding

POST /spaces/{slug}/event-contracts/{contract_id}/registry-bindings
Content-Type: application/json
{
"connection_id": "f74652cc-e90b-4678-a845-67438beb76d3",
"binding_role": "value",
"remote_reference_type": "subject",
"subject_strategy": "topic_name",
"desired_compatibility_mode": "BACKWARD"
}

binding_role values are key, value, event, and entity. remote_reference_type values are subject, artifact, and iglu. subject_strategy values are topic_name, record_name, topic_record_name, and manual.

When subject_strategy is manual, subject is required. Otherwise the service can generate a subject from contract metadata, Kafka topic binding, record name, and binding role. Iglu bindings require vendor, name, format, and version, either in the payload or in the current contract version's self block.

Binding Response

{
"id": "48a0992e-b442-40a5-82ab-0c41671dbde9",
"space_id": "82d7d96a-b7f5-4d19-8bb9-42127bb6399c",
"contract_id": "13db74fd-e99f-4929-aad7-32c330c707f6",
"connection_id": "f74652cc-e90b-4678-a845-67438beb76d3",
"provider": "confluent",
"binding_role": "value",
"remote_reference_type": "subject",
"subject": "orders.order.created-value",
"resolved_identity": "subject:orders.order.created-value",
"subject_strategy": "topic_name",
"desired_compatibility_mode": "BACKWARD",
"remote_compatibility_mode": null,
"sync_status": "pending",
"remote_version": null,
"remote_schema_id": null,
"remote_global_id": null,
"remote_content_id": null,
"remote_checksum": null,
"last_pushed_version_id": null,
"last_pulled_version_id": null,
"conflict_details": null,
"last_synced_at": null,
"created_at": "2026-06-26T10:30:00Z",
"updated_at": "2026-06-26T10:30:00Z"
}

Push And Compatibility Sync

Push writes an approved local version to the remote registry:

POST /spaces/{slug}/event-contracts/{contract_id}/registry-bindings/{binding_id}/push
Content-Type: application/json
{
"version_id": "c7a96891-092f-4d37-979b-246f42c5f449",
"sync_compatibility": true
}

If version_id is omitted, Qarion uses the contract's latest approved version. Draft versions cannot be pushed. A provider/format mismatch returns a validation error. Successful pushes update remote IDs, checksum, last_pushed_version_id, last_synced_at, and set sync_status to clean.

Compatibility sync reads or sets the remote compatibility mode:

POST /spaces/{slug}/event-contracts/{contract_id}/registry-bindings/{binding_id}/compatibility-sync
Content-Type: application/json
{
"desired_compatibility_mode": "BACKWARD"
}

Supported compatibility mode values are normalized to uppercase underscore forms. If the remote mode differs from the desired mode after sync, the binding becomes conflicted and conflict_details records the desired and remote values. Iglu bindings skip Confluent-style compatibility sync and become clean.

Runtime Registry

Runtime endpoints resolve approved local Event Contract versions. They do not fetch from external schema registries at request time.

GET /registry/events/orders.order.created/latest-approved?space=finance
GET /registry/events/orders.order.created/versions/1.0.0?space=finance
GET /registry/events/orders.order.created/schema?space=finance
GET /registry/iglu/schemas/com.example/orders_order_created/jsonschema/1-0-0?space=finance

Specific version and Iglu schema responses include:

Cache-Control: public, max-age=31536000, immutable

Use the optional space query parameter when event names may exist in multiple spaces.

Error Reference

StatusCause
400Invalid schema payload, unsupported provider, unsupported subject strategy, unsupported compatibility mode, missing manual subject, missing Iglu identity, unsupported provider/format push, or pushing a non-approved version.
403Missing Event Contract permission or impersonated user on a non-impersonation sync route.
404Space, schema entry, contract, version, connection, binding, source system, credential, or remote schema was not found.
409Commonly used by service-level conflicts such as duplicate external connection names or duplicate registry identities.
422Pydantic validation failure, for example an invalid UUID, invalid URL, or remote-references limit outside 1..200.

Operational Notes

  • Live external registry tests are opt in. The repository runbook is docs/operations/event-contract-schema-registry.md.
  • Auth modes are none, api_key, bearer, and basic. API key auth can use api_key_header and api_key_prefix in connection or credential config.
  • Confluent and Apicurio support explicit compatibility sync. Iglu uses self-describing SchemaVer schemas and does not fabricate compatibility modes.
  • External registry sync is manual through pull, push, and compatibility-sync actions. default_sync_direction is stored for rollout policy and UI defaults.