damngoodprompts

Structured data extraction

Use the provider's schema feature when one exists, and make null handling part of the contract.

Last reviewed: August 25, 2026ChatGPTGeminiClaudeGrokMistral
Technique

Best suited to ChatGPT - native Structured Outputs are built for schema-constrained extraction and reduce malformed JSON compared with prompt-only formatting

The task

You need to pull fields, categories, or entities out of unstructured text and return a stable shape your code can parse. If “schema” or “JSON mode” is new to you, start with structured output prompting.

Why the old approach is outdated

Older prompts described the desired format in prose: “Return JSON with name, date, and category.” Some templates also prefilled the assistant response with { to push the model toward JSON.

That is weaker than the current API behavior. OpenAI, Gemini, Claude, xAI, and Mistral now document structured-output features where a schema is passed as part of the request. Use that request field when it exists. The prompt should explain the extraction rules, while the API schema defines the output contract.

The current approach

Write the prompt as extraction rules, not as a format enforcement trick.

Extract the fields from the support ticket.

Rules:
- Use null when a field is not present.
- Do not infer an urgency level from tone alone.
- Keep the summary to one sentence.

Ticket text:
{{ticket_text}}

Then pass the schema through the provider’s API feature.

{
  "model": "gpt-5.6-terra",
  "input": [
    {
      "role": "user",
      "content": "Extract the fields from this support ticket. Use null when a field is not present.\n\n{{ticket_text}}"
    }
  ],
  "text": {
    "format": {
      "type": "json_schema",
      "name": "support_ticket",
      "schema": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "customer_name": { "type": ["string", "null"] },
          "issue_category": {
            "type": "string",
            "enum": ["billing", "technical", "account_access", "other"]
          },
          "urgency": {
            "type": "string",
            "enum": ["low", "medium", "high"]
          },
          "summary": { "type": "string" }
        },
        "required": ["customer_name", "issue_category", "urgency", "summary"]
      }
    }
  }
}

API differences that matter

OpenAI uses text.format for Structured Outputs in the Responses API. Gemini’s structured output docs use a response_format object with mime_type: "application/json" and a schema field. Claude documents output_config.format with type: "json_schema". xAI and Mistral also document schema-backed structured outputs.

The prompt text can stay mostly the same across providers. The request wrapper should not. Treat the schema as code and validate the returned object after the call, especially if the data will write to a database or trigger an action.

For batch extraction

State edge-case behavior once and keep each source item independent.

Process each document independently. If a document is not a support ticket, return:
{"error": "does not match expected format"}

Do not borrow fields from one document to complete another.

What to avoid

  • Prefilling a response with { to force JSON. Use the provider’s schema feature instead.
  • Describing the schema only in prose when the API can enforce a schema.
  • Leaving null handling unspecified. Without a rule, the model may invent plausible values.
  • Reusing one provider’s API shape across providers. The prompt can travel, but the request wrapper changes.

Source set