Skip to main content
By default, CatchAll generates response schemas dynamically—field names can change between jobs, even with identical inputs. This guide shows how to build integrations that handle this variability and how to define custom enrichments to ensure consistent field names.

Guaranteed vs variable fields

Every response includes record_id, record_title, and citations. Field names in enrichment are variable with automatic generation, or consistent when you define custom enrichments.

Why schemas vary

Submit the same query twice, get different field names:
{
  "record_id": "5262823697790152939",
  "record_title": "Oracle Q1 2026 Earnings Exceed Expectations",
  "enrichment": {
    "company_name": "Oracle",
    "revenue": "$14.9 billion",
    "profit_margin": "42%"
  }
}
Why this happens:
  • LLMs generate extractors dynamically for each job
  • Different keywords, validators, and extractors are created
  • Field names are chosen semantically to match content
This is expected behavior, not a bug.

Get enrichment suggestions

Use the initialize endpoint to see suggested enrichments for your query:
from newscatcher_catchall import CatchAllApi

client = CatchAllApi(api_key="YOUR_API_KEY")

suggestions = client.jobs.initialize_job(
    query="Executive departures at Fortune 500 technology companies",
    context="Include executive name, position, company name, departure date"
)

print(suggestions.enrichments)
Suggested enrichments:
{
  "enrichments": [
    {
      "name": "executive_name",
      "description": "Extract the name of the departing executive",
      "type": "text"
    },
    {
      "name": "executive_position",
      "description": "Extract the position or title of the departing executive",
      "type": "text"
    },
    {
      "name": "subject_company",
      "description": "Extract the name of the company from which the executive is departing",
      "type": "company"
    },
    {
      "name": "departure_date",
      "description": "Extract the date of the executive's departure",
      "type": "date"
    },
    {
      "name": "departure_reason",
      "description": "Extract the stated reason for the executive's departure if available",
      "type": "text"
    }
  ]
}
These suggestions help you understand possible enrichments before submitting. You can use them as-is, modify them, add more, or ignore them and let the system generate fresh enrichments when you submit the job.

Define custom enrichments

Submit enrichments in your request for consistent field names:
from newscatcher_catchall import CatchAllApi

client = CatchAllApi(api_key="YOUR_API_KEY")

# Use suggested enrichments (modified: removed departure_reason, kept 4 fields)
job = client.jobs.create_job(
    query="Executive departures at Fortune 500 technology companies",
    context="Include executive name, position, company name, departure date",
    enrichments=[
        {
            "name": "executive_name",
            "description": "Extract the name of the departing executive",
            "type": "text"
        },
        {
            "name": "executive_position",
            "description": "Extract the position or title of the departing executive",
            "type": "text"
        },
        {
            "name": "subject_company",
            "description": "Extract the name of the company from which the executive is departing",
            "type": "company"
        },
        {
            "name": "departure_date",
            "description": "Extract the date of the executive's departure",
            "type": "date"
        }
    ]
)
Every job returns the same field names:
{
  "record_id": "12345",
  "record_title": "John Smith Departs Apple as CFO",
  "enrichment": {
    "executive_name": "John Smith",
    "executive_position": "Chief Financial Officer",
    "subject_company": {
      "name": "Apple Inc.",
      "alternative_names": ["Apple"],
      "website_candidates": ["apple.com"],
      "people": ["Tim Cook (CEO)"],
      "address": "Cupertino, California, USA"
    },
    "departure_date": "2026-01-15"
  }
}
See Create job endpoint for all enrichment types.

Working with dynamic schemas

If you don’t define custom enrichments, field names vary between jobs. Handle this with pattern matching:
def find_field(enrichment, patterns):
    """Find first field matching any pattern."""
    for key, value in enrichment.items():
        if any(pattern in key.lower() for pattern in patterns):
            return value
    return None

# Usage - handles "revenue", "total_revenue", "sales", etc.
revenue = find_field(record["enrichment"], ["revenue", "sales"])
company = find_field(record["enrichment"], ["company", "company_name"])

See also