15 seconds

The payload lied.

A partner posts a ticket without an owner. Your handler inserts null. The AI later invents one.

POST /ticketsRaw JSONPydanticTrust boundaryPostgresOnly clean rows
Lesson notesValidate at the trust boundary: the short version+

Week 3 · Data audits & API trust boundary · about 3 minutes

What you will be able to do

Reject bad ticket payloads with Pydantic before they touch Postgres or the model.

The idea

The trust boundary is the edge of your service. Everything outside can be wrong, hostile or incomplete. Pydantic models define what may enter.

If owner is required, a missing owner is a 422, not a silent null. The AI layer only sees rows that already passed the contract.

from typing import Literal
from pydantic import BaseModel, Field

class TicketIn(BaseModel):
    title: str = Field(min_length=1, max_length=200)
    owner: str = Field(min_length=1)
    priority: Literal["low", "med", "high"]

@app.post("/tickets")
def create_ticket(body: TicketIn) -> TicketOut:
    return save(body)  # only validated data reaches save()

Do not "fix it up" for the model. Reject it at the door.

Key takeaways

  • Validate inbound JSON with an explicit model.
  • Required fields fail closed (422), not with nulls.
  • The AI layer should never be your schema enforcer.

Part of the Forward Deployed Engineer roadmap. New to the role? Start with what a Forward Deployed Engineer does.