Skip to main content

The silent failure

Your pipeline extracts structured data from inbound emails:
{
  "sender": "jane@acme.com",
  "subject": "URGENT: Server down in production",
  "intent": "urgent_support",
  "priority": "low",
  "department": "sales"
}
Valid JSON. Schema passes. Your ticketing system routes it to the sales team with low priority. But the subject line says “URGENT” and the intent is urgent_support. A priority of low and a department of sales makes no sense. A production outage sits in the wrong queue for hours.

With Boundary

Attempt 1 → { sender: "jane@acme.com", intent: "urgent_support", priority: "low", department: "sales" }
             ✕ urgent intent requires priority "high" or "critical"
             ✕ support intent must route to engineering or support, not sales
             ↻ violations sent back to model

Attempt 2 → { sender: "jane@acme.com", intent: "urgent_support", priority: "critical", department: "engineering" }
             ✔ all rules pass
             ✔ ACCEPTED — safe for ticket routing

The contract

import { z } from "zod";
import { defineContract } from "@withboundary/contract";

const schema = z.object({
  sender: z.string().email(),
  subject: z.string(),
  intent: z.enum(["general_inquiry", "billing", "urgent_support", "feature_request", "cancellation"]),
  priority: z.enum(["low", "medium", "high", "critical"]),
  department: z.enum(["sales", "support", "engineering", "billing", "product"]),
  summary: z.string(),
});

const emailContract = defineContract({
  schema,
  rules: [
    // urgent intent must have high or critical priority
    (e) => !e.intent.includes("urgent") || ["high", "critical"].includes(e.priority)
      || `urgent intent "${e.intent}" has priority "${e.priority}" (needs high or critical)`,

    // support intents go to support or engineering, not sales
    (e) => !e.intent.includes("support") || ["support", "engineering"].includes(e.department)
      || `support intent routed to "${e.department}" (needs support or engineering)`,

    // cancellation intent must go to billing or support
    (e) => e.intent !== "cancellation" || ["billing", "support"].includes(e.department)
      || "cancellation requests must route to billing or support",

    // summary must be substantive
    (e) => e.summary.length > 20
      || "summary too short — needs enough context for the receiving team",
  ],
});

Full example

const result = await emailContract.accept(async (attempt) => {
  const res = await openai.chat.completions.create({
    model: "gpt-4o",
    messages: [
      {
        role: "system",
        content: attempt.instructions,
      },
      {
        role: "user",
        content: `Parse this email:\n\nFrom: jane@acme.com\nSubject: URGENT: Server down in production\nBody: Our main API server has been returning 500 errors for the last 30 minutes...`,
      },
      ...attempt.repairs,
    ],
  });
  return res.choices[0].message.content;
});

if (result.ok) {
  // ✔ safe to create ticket
  await ticketSystem.create({
    from: result.data.sender,
    priority: result.data.priority,
    department: result.data.department,
    summary: result.data.summary,
  });
}

Result: safe for ticket routingEvery parsed email is validated for cross-field consistency. Intent matches priority. Department matches intent. Urgent issues never get low priority. Your support team sees the right tickets in the right queue.

When to use this pattern

  • Inbound email triage and routing
  • Customer support ticket classification
  • Email-to-CRM data extraction
  • Newsletter/digest content parsing
  • Invoice emails with structured data