---
title: "Renders a client-message template for a real client so staff can edit it in the composer before sending (ITE-1171). Values come from the tenant's records — client, and optionally the patient, appointment and estimate, each of which must belong to the client. Returns plain text for the channels the template claims, plus every {{Token}} left unfilled. Archived templates still render: a draft opened before the archive shouldn't break."
method: POST
path: "/templates/{id}/render"
tags: ["Templates"]
---

# Renders a client-message template for a real client so staff can edit it in the composer before sending (ITE-1171). Values come from the tenant's records — client, and optionally the patient, appointment and estimate, each of which must belong to the client. Returns plain text for the channels the template claims, plus every {{Token}} left unfilled. Archived templates still render: a draft opened before the archive shouldn't break.

`POST /templates/{id}/render`

## Request

- Base URL: `https://api.clinicos.vet/backend/business`
- URL: `https://api.clinicos.vet/backend/business/templates/{id}/render`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/clinicos/apis/pawthosx-business-api-v1/docs/templates/:id/render/post.ts> (a function with typed inputs; its response is checked against the schema)

## Path parameters

- `id` string, required

## Request body

- RenderClientMessageRequestDto: POST /templates/{id}/render (ITE-1171): render a client-message template for a real client so staff can edit it in the composer. Only the client is required; each other record adds the merge fields it can fill and must belong to that client.
  - `clientId` string
  - `patientId` string, nullable
  - `appointmentId` string, nullable
  - `estimateId` string, nullable: The estimate (treatment plan) an estimate follow-up is about.

## Response `200`

OK

- ClientMessageRenderResultDto: A client-message template with the client's real values substituted. Plain text, values as stored — the composer shows it for editing, and the send path encodes it for the email's HTML. Only the channels the template claims are returned.
  - `templateId` string
  - `templateName` string
  - `category` string, nullable
  - `channel` string, nullable
  - `emailSubject` string, nullable
  - `emailBody` string, nullable
  - `smsBody` string, nullable
  - `unresolvedTokens` string[]: Every {{Token}} still in the returned text, in order of first appearance: fields with no single data source (ReferralClinicName, EstimateLink…), fields whose record wasn't given or is blank, and tokens that aren't merge fields for the category. Staff fill or remove each one before the composer lets the message go.

## Other responses

- `400`: Bad Request
- `404`: Not Found

## Changes

- **2026-10-28** `099cf36186e0`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/clinicos/apis/pawthosx-business-api-v1/changes/templates/:id/render/post.md)

---

[API](https://skmtc.dev/clinicos/apis/pawthosx-business-api-v1.md) - [All operations](https://skmtc.dev/clinicos/apis/pawthosx-business-api-v1/llms.txt) - [OpenAPI document](https://skmtc.dev/clinicos/apis/pawthosx-business-api-v1/revisions/099cf36186e0?raw)
