Schema evolution in extraction is the work of changing the schema you extract into, while the sources you extract from change on their own. The safe pattern is simple: add fields as optional, version every schema, tag every record with the version it was extracted under, and treat validation failures as signals instead of noise. This guide covers which changes are safe, how to migrate, and how to make drift visible before it corrupts anything downstream.
TL;DR
- Adding an optional field, or one with a default, is the safe change. Renames, type changes and new required fields are the ones that break consumers.
- Store schemas as versioned files, and write a
schema_versioninto every extracted record. - Migrate in four steps: add the field as nullable, confirm extraction, update consumers, then promote it to required.
- Drift is silent unless the API returns typed failures. Validate every response and alert on violation rates, not just on errors.
- Check pricing for failure cases before you commit to an extraction API. Retries on drifted pages add up.
Table of Contents
- Why extraction schemas change
- Which schema changes are safe and which break
- Version extraction schemas like code
- A migration sequence that does not page you at 2 a.m.
- Detect drift with typed failures, not guesses
- Keep extracted data stable for RAG and downstream apps
- Our perspective
- What to check before choosing an extraction API
- Try it on your own schema
- FAQ
- Sources
Why extraction schemas change
There are two sources of change, and they need different handling.
Your requirements change. A product team wants a currency field next to price. A compliance workflow needs a source_url on every value. You control this change, so you can version and coordinate it.
The source changes. A site redesigns its pricing page. A field moves into a tab. A label goes from "Price" to "Starting at". You do not control this change, and nobody tells you. For almost any web source, drift is the default state of a long-running pipeline. The practical question is not whether a source will change. It is whether your pipeline notices before downstream consumers are corrupted.
Both kinds of change land in the same place: a mismatch between the schema you declared and the data you got back.

Which schema changes are safe and which break
The rules come from data serialization formats, and they apply to JSON extraction schemas just as well. One compatibility breakdown for pipelines sorts the common changes this way:
| Change | Compatibility |
|---|---|
| Add a field with a default | Fully compatible |
| Add a field without a default | Forward-only |
| Remove a field that has no default | Backward-only |
Widen int to bigint | Backward-only |
| Rename a field | Breaking, unless the format supports aliases |
Change string to int | Breaking |
A few details are worth knowing. In Avro, backward compatibility holds only when new fields are optional or have defaults. A rename is treated as deleting the old field and adding a new one, so any consumer expecting the old name breaks. Reordering fields can corrupt data in binary formats, because the encoding relies on field sequence. JSON is more forgiving about order, but the rename and type rules still apply.
For extraction schemas, add one more rule: narrowing an enum is a breaking change. If your schema says availability is one of in_stock or out_of_stock and a source starts publishing "preorder", you have a value that fits no option. Decide in advance whether that becomes null, an other bucket, or a validation failure.
Version extraction schemas like code
Treat a schema as a production artifact, not a runtime string.
- Keep one schema file per document or page type, in the same repository as the code that consumes it. Review changes in pull requests.
- Use semantic versioning. A new optional field is a minor bump. A rename, type change or new required field is a major bump.
- Write the version into the output. Embedding a
schema_versionfield in extracted data lets you keep multiple model versions in parallel and tag each result with the schema that produced it. - Handle old records deliberately. For breaking changes, either re-extract lazily or transform on read. Do not rewrite history silently.
If you define schemas as Pydantic models, versioning maps cleanly onto Python modules such as ProductV1 and ProductV2. We cover that workflow in Pydantic web extraction with Gyrence.
A migration sequence that does not page you at 2 a.m.
For a new required field, do not ship it as required on day one. Use this order:
- Add the field as nullable in the new schema version.
- Run extraction and confirm the field is actually populated across a representative sample of sources.
- Update every consumer to read the field and handle
null. - Promote the field to required in the next major version.
Then verify. Sample old documents through the new schema and confirm they either migrate cleanly or fail explicitly with a clear error about the missing required fields. New extractions should come back tagged with the new version. A migration that fails loudly is a good migration. A migration that fills in guesses is a data quality incident waiting to happen.
Detect drift with typed failures, not guesses
Schema evolution you plan is manageable. Drift you do not see is the real risk, because a changed page rarely throws an exception. It returns a plausible-looking object with an empty field, a wrong field, or a field in the wrong format.
Three practices catch it:
- Validate every response against the schema. Schema validation (is the shape right?) and semantic validation (does the value make sense?) are separate checks. A price of
-1passes the first and fails the second. - Track violation rates per source. One failed record is noise. A source going from 1% to 40% violations overnight is a layout change.
- Keep failures first-class in the response. If your API returns only success or an exception, you have no way to tell "page was empty" from "page changed shape" from "blocked". Typed, discriminated-union responses let your code branch on the exact case.
This is the design we built Gyrence around. Every call returns a typed response, including the failure cases, so an agent or pipeline can reason about what happened instead of guessing. Our write-up on structured data extraction with schema validation shows the pattern in code.
Outside the extraction layer, the same discipline applies to anything that emits structured output. The idea behind automated schema validation testing is the same: run checks on a schedule so a silent change in format surfaces as a failed test instead of a surprise.
For page-level change, WebDoppler monitors sources and sends webhook alerts, so you hear about a changed page before your validators start failing.
Keep extracted data stable for RAG and downstream apps
RAG ingestion is where schema drift hurts quietly. A vector store full of records with inconsistent fields retrieves inconsistent context, and nobody sees an error.
- Normalize types and units at the boundary: dates to ISO 8601, prices to a number plus a currency code.
- Keep a stable internal schema and map each source into it. Source labels change. Your field names should not.
- Store
source_url, a fetch timestamp andschema_versionwith every record. Source-traceable data is the difference between an answer you can defend and one you cannot. - Deduplicate after normalization, not before.
Our perspective
Most extraction tooling is built for the day the demo works. We build for the day six months later when a source ships a redesign and nobody told you.
That is why we think failure modes belong in the contract. A scraper that returns an empty string for a missing field has made a decision on your behalf and hidden it. We would rather hand you a typed response that says exactly what happened, so your code, or your agent, can decide.
The same goes for cost. Schema evolution means re-running extraction: backfills, retries, re-extraction after a migration. On a bill that charges separately for AI extraction, every one of those runs is a surprise. Gyrence has no separate AI extraction charge, and spending caps keep a backfill from becoming an incident.
Version your schemas, tag your records, validate everything, and pick tools that tell you the truth when a page changes.
Glen
What to check before choosing an extraction API
When your schemas will change, the questions to ask about any API are about the unhappy path:
- Are failures typed? You need to tell drift from blocking from empty pages.
- What does a failed or retried call cost? Ask whether failures consume credits.
- Is LLM extraction billed separately? Re-extraction after a migration multiplies this line item.
- Can you cap spend? A hard cap turns a runaway backfill into a paused job.
- Does it work through MCP? If agents call the tool, the response types are the agent's only way to reason about results.
Try it on your own schema
Gyrence gives you five primitives (Search, Traverse, Fetch, Extract, Map), a hosted MCP endpoint, spending caps and typed responses. Paid workspace plans are Standard at $75 per month, Growth at $299 per month and Scale at $549 per month. There are also Free, Founders and Pay-As-You-Go options. See the details on the pricing page.
If you are wiring this into an agent, start with Gyrence for AI agents.
FAQ
What is schema evolution in data extraction?
It is the process of changing an extraction schema over time as requirements and sources change. It covers adding, removing, renaming and retyping fields while keeping existing consumers and stored data working.
Is adding a field a breaking change?
Not if the field is optional or has a default. Adding a required field with no default breaks consumers that do not yet supply or expect it, so add it as nullable first and promote it later.
How do I know when a website change has broken my schema?
Validate every extraction against the schema and track violation rates per source. A sudden jump for one domain usually means its layout changed. Page monitoring with webhook alerts can flag the change even earlier.
Should I re-extract old data after a breaking change?
It depends on the volume and the value of the old records. Lazy re-extraction when a record is next needed is cheaper than a full backfill, and a transform on read works when the new schema can be derived from the old data.
Sources
- Handling Schema Drift in Long-Running Extraction Pipelines
- Schema Evolution: Advanced, Pipeline Architecture Lesson
- Backward Compatibility in Schema Evolution: Guide
- Schema versioning and migration, Data Extraction Advanced

