---
key: api.response-dtos
title: 2026-07 — Response DTOs live in `ErsatzTV.Core/Api`, file-scoped `#nullable enable`
status: active
since: 2026-07
supersedes: none
superseded-by: none
rule: New REST response DTOs live in `ErsatzTV.Core/Api/<Domain>/*ResponseModel.cs` with a file-scoped `#nullable enable` pragma; controllers never expose Application VM types directly.
signals: 'nullable-disabled Core project, ResponseModel mirroring ViewModel shape · paths: `ErsatzTV.Core/Api`, `docs/api-conventions.md` §2 · issues: none cited'
mechanics: '`docs/api-conventions.md` §2'
---

New REST response DTOs go in `ErsatzTV.Core/Api/<Domain>/*ResponseModel.cs` and mirror the shape of
the corresponding Application-layer ViewModel — controllers never expose VM types directly. Because
`ErsatzTV.Core.csproj` sets `<Nullable>disable</Nullable>` project-wide, any response-model file
with an optional member needs its own `#nullable enable` pragma at the top (most already have one).
`ErsatzTV.Application` has no nullable context at all — do not add `?` annotations to types living
there; that's a Core/Api-layer-only convention. Full detail: `docs/api-conventions.md` §2.
