Auditing and improving existing models
Auditing and improving existing models
TL;DR
- Audit when you see signals: 40+ field content types, fields named *_v2 or temp_*, or editors consistently skipping fields.
- Export schemas and measure field population rates before proposing changes -- data beats opinions.
- Split oversized content types into focused types connected by references; extract repeated field groups into Global Fields.
- Treat every UID change as a coordinated migration, not a rename -- it breaks every API consumer that references the old key.
Content models degrade over time. Fields accumulate because removing them feels risky. Content types expand because adding one more field is easier than creating a new content type. Naming conventions drift as different developers contribute at different times. Six months after launch, the model that seemed clean at kickoff has become a source of editor confusion and developer frustration.
This lesson covers how to systematically audit an existing content model, identify structural problems, and improve the model without breaking production.
When to audit
An audit is not a scheduled ceremony. It is a response to specific signals:
- Editors complain that entry forms are overwhelming or confusing
- Developers find the API response includes dozens of fields they never render
- New feature requests require workarounds because the model does not fit
- Onboarding a new team member takes longer than expected because the model is hard to explain
- Content types have fields with names like old_description, banner_v2, or temp_promo
If any of these sound familiar, the model needs attention.
Red flags in a content model
Before diving into a formal audit process, learn to recognize the symptoms of model problems at a glance.
Content types with 40+ fields
When a single content type has 40 or more fields, editors scroll through a form that feels like a bureaucratic document. They skip optional fields because they cannot find them. They fill in wrong fields because similar names blur together. From the API side, every response includes dozens of keys, most of which any given consumer ignores.
Unused fields that editors skip
If a field has been empty across 90% of entries for six months, it is either unnecessary or poorly understood. Either way, it is noise in the editorial interface and in the API payload.
Fields with confusing names
Field UIDs like cta_link_2, hero_text_alt, or misc_data tell editors nothing about what to enter and tell developers nothing about what to expect. Clear naming is not cosmetic - it is an operational requirement.
Reference chains 4+ levels deep
When assembling a single page requires resolving references through 4 or more levels of content types, query performance degrades and the editorial mental model becomes unwieldy. If an editor needs to understand Article > Author > Department > Campus > Region to create a news post, the model is over-normalized.
Dual-purpose content types
A content type that serves as both a "page" and a reusable "component" creates ambiguity. Editors do not know if they are creating standalone content or a building block. Developers do not know if they should render it as a full page or embed it within another layout.
The audit process
Step 1: export content type schemas
Start with a complete picture. Use the Content Management API to export all content type schemas from your stack:
curl -X GET "https://api.contentstack.io/v3/content_types" \
-H "api_key: YOUR_API_KEY" \
-H "authorization: YOUR_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" | jq '.content_types[] | {uid, title, schema_length: (.schema | length)}'This gives you a list of every content type with its UID, title, and field count. Sort by schema_length descending. Content types with the highest field counts are your first audit targets.
To export a single content type's full schema for detailed review:
curl -X GET "https://api.contentstack.io/v3/content_types/product" \ -H "api_key: YOUR_API_KEY" \ -H "authorization: YOUR_MANAGEMENT_TOKEN" \ -H "Content-Type: application/json" | jq '.content_type.schema'
Step 2: analyze field usage
Exporting schemas tells you what fields exist. The next question is: which fields are actually populated? Query entries and check for empty vs populated fields.
Write a script that iterates through entries and counts how many times each field has a non-null, non-empty value. Fields with less than 10% population across entries are candidates for removal or reclassification.
Step 3: interview editors
Data analysis reveals structural problems. Editor interviews reveal usability problems. Ask specific questions:
- "Walk me through creating a [content type] entry. Where do you pause or get confused?"
- "Are there fields you always skip? Which ones and why?"
- "When you need to update [specific content], how many entries do you touch?"
- "Have you ever entered content in the wrong field?"
Document the answers. They form the qualitative half of your audit evidence.
Step 4: map API consumers
Identify every frontend, service, or integration that reads from each content type. For each consumer, document which fields it actually uses. Fields that no consumer reads and no editor populates are dead weight.
Worked example: the 47-field Product content type
Consider a retail site with a Product content type containing 47 fields. On inspection, the fields span four distinct concerns:
Marketing content (12 fields): product_name, tagline, marketing_description, hero_image, lifestyle_images, video_url, brand_story, key_benefits, comparison_chart, social_proof_quote, campaign_badge, seasonal_flag
Technical specifications (15 fields): weight, dimensions_l, dimensions_w, dimensions_h, material, color_options, size_chart, care_instructions, warranty_info, certifications, country_of_origin, battery_type, connectivity, operating_temp, model_number
Inventory and pricing (10 fields): sku, price, sale_price, currency, stock_status, restock_date, min_order_qty, max_order_qty, fulfillment_warehouse, shipping_class
SEO metadata (10 fields): meta_title, meta_description, og_image, og_title, canonical_url, focus_keyword, schema_markup, breadcrumb_label, url_slug, sitemap_priority
Four different audiences create and consume these fields. Marketing editors write the marketing content. Product managers maintain technical specs. An inventory system syncs pricing and stock data via the Management API. SEO specialists manage the metadata. Forcing all four audiences into one 47-field form creates problems for everyone.
Improvement techniques
Splitting large content types
The 47-field Product should become multiple coordinated content types:
- Product (core): product_name, sku, hero_image, marketing_description, brand_story. This is what editors primarily work with.
- Product Specs (referenced): weight, dimensions, material, certifications, etc. Created once, referenced by Product.
- SEO Metadata (Global Field): meta_title, meta_description, og_image, canonical_url, etc. Applied as a Global Field across Product and other content types that need SEO data (see lesson 2.1.3 for Global Fields).
Inventory and pricing fields (price, stock_status, fulfillment_warehouse) should be removed from Contentstack entirely. They change based on business logic, not editorial decisions. Store them in your commerce platform and join them with CMS content at the frontend or API gateway layer.
After this restructuring, the Product content type drops from 47 fields to roughly 10-12. Editors see a focused form. The API response for a product is lean and predictable.
Renaming fields
Field renaming in Contentstack requires care. The display name can be changed at any time without API impact - this is purely a UI label for editors. The UID is the API contract. Changing a UID changes the JSON key in every API response, which breaks every consumer that references that key.
If you must change a UID:
- Create the new field with the desired UID
- Migrate data from the old field to the new field (using the Management API)
- Update all API consumers to use the new field
- Verify in all environments
- Remove the old field
This is a coordinated change, not a casual rename. Plan it as a migration, not a configuration update.
Deprecating unused fields
For fields that are no longer needed but contain historical data:
- Update the field's description to include "[DEPRECATED - Do not use]"
- Remove the mandatory flag if set
- Communicate the deprecation to editors and developers
- After a grace period (typically one release cycle), hide the field or remove it
- Before removal, export entries that contain data in the deprecated field as a backup
Adding Global Fields for repeated patterns
If your audit reveals the same group of fields repeated across multiple content types - SEO metadata, social sharing configuration, CTA buttons - extract them into a Global Field. This reduces duplication, ensures consistency, and makes future changes to those field groups a single operation instead of N content type updates.
Migration considerations
Modifying a content type that has existing entries is not risk-free. Understand what happens:
- Adding a new field: existing entries gain the field with a null/empty value. No data loss. Safe.
- Removing a field: existing entry data for that field is permanently deleted when the content type is saved. Not reversible. Always export entry data before removing fields.
- Changing field type: not directly supported. You must create a new field, migrate data, and remove the old field.
- Making a field mandatory: existing entries that lack data for that field will need to be updated before they can be saved again. This can block editorial workflows if not communicated.
Use the Management API for bulk data migration when restructuring:
# Update an entry to populate a new field with data from an old field
curl -X PUT "https://api.contentstack.io/v3/content_types/product/entries/ENTRY_UID" \
-H "api_key: YOUR_API_KEY" \
-H "authorization: YOUR_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"entry": {
"new_field_uid": "migrated value from old field"
}
}'For large-scale migrations, the Contentstack CLI's export and import commands provide a more structured approach (see lesson 3.3.3 for CLI migration patterns).
Common mistakes
Common pitfall: Removing a field from a content type permanently deletes that field's data across all entries the moment the content type is saved. There is no undo. Always export entry data for the field before removing it, even if you believe the field is unused -- your audit may have missed entries in non-default locales or unpublished drafts.
Auditing without data. Opinions about content model quality are useful. Usage data is better. Export schemas, count field populations, and interview editors before proposing changes. An audit driven by developer preference rather than evidence often creates different problems instead of solving existing ones.
Making breaking changes without a migration plan. Removing a field, changing a UID, or restructuring references without coordinating with every API consumer causes production failures. Every structural change needs: a list of affected consumers, a migration script, a rollback plan, and a communication timeline.
Perfecting the model instead of improving it. An audit should produce incremental improvements, not a ground-up redesign. Splitting one 47-field content type into three focused content types is a meaningful improvement. Redesigning the entire stack's content architecture because the audit revealed naming inconsistencies is over-correction.