---
title: "Update an existing egress template"
method: PUT
path: "/api/v1/egress-templates/{templateId}"
tags: ["EgressTemplate"]
---

# Update an existing egress template

`PUT /api/v1/egress-templates/{templateId}`

Updates the metadata and/or mapping CSV of an existing egress template and increments its version.

When to use: call this to replace the column-mapping CSV or change configuration on a template previously created with `POST /api/v1/egress-templates`.

Partial-update semantics: only fields explicitly included in the request are changed; omitted fields keep their current stored values. `entityType` is immutable and is not an accepted field on this endpoint — it is always taken from the existing record.

Preconditions: `tenant-id` header must be present. The template must belong to the requesting tenant; cross-tenant access returns 404 (not 403). `status`, if supplied, is limited to `draft` or `active` — `inactive` is rejected with 400 on update.

Side effects: if a new CSV is supplied, it is uploaded to GCS at a new versioned path and the previous CSV object is left in place. Unlike create, a data-store write failure after a successful CSV upload does not roll back the new GCS object. `file` is optional; when omitted, the existing CSV is preserved.

Schedule field rules: the same daily/weekly/monthly/custom interdependencies as `POST /api/v1/egress-templates` apply.

Returns: the updated `EgressTemplateResponse` with the incremented `version` and, if a new CSV was uploaded, the updated `mappingsCsvUrl`.

## Path parameters

- `templateId` string, required

## Headers

- `tenant-id` string
- `x-user-id` string

## Response `200`

The updated egress template, with incremented version and, if a new CSV was uploaded, the updated mappings CSV URL

- EgressTemplateResponse
  - `id` string — Server-assigned unique identifier of the template.
  - `tenantId` string — ID of the tenant that owns this template.
  - `createdAt` string, date-time
  - `createdBy` string — ID of the user who created the template.
  - `updatedAt` string, date-time
  - `updatedBy` string — ID of the user who last updated the template.
  - `templateName` string — Human-readable template name.
  - `description` string — Free-text description of the template's purpose.
  - `entityType` string — Entity type this template maps: `practitioner`, `facility`, or `group`. Immutable after creation.
  - `outputFormat` string — Output file format produced by exports run from this template, e.g. `csv`.
  - `separator` string — Delimiter used in the output CSV.
  - `status` string — Template lifecycle status: `draft`, `active`, or `inactive` (soft-deleted).
  - `version` integer — Version number, incremented on each successful update. Not incremented by delete.
  - `mappingsCsvUrl` string — GCS URL of the current mapping CSV for this template version.
  - `rowExpansionKeys` JsonNode
    - `empty` boolean
    - `valueNode` boolean
    - `containerNode` boolean
    - `missingNode` boolean
    - `array` boolean
    - `object` boolean
    - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
    - `pojo` boolean
    - `number` boolean
    - `integralNumber` boolean
    - `floatingPointNumber` boolean
    - `short` boolean
    - `int` boolean
    - `long` boolean
    - `float` boolean
    - `double` boolean
    - `bigDecimal` boolean
    - `bigInteger` boolean
    - `textual` boolean
    - `boolean` boolean
    - `null` boolean
    - `binary` boolean
  - `extExportConfig` JsonNode
    - `empty` boolean
    - `valueNode` boolean
    - `containerNode` boolean
    - `missingNode` boolean
    - `array` boolean
    - `object` boolean
    - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
    - `pojo` boolean
    - `number` boolean
    - `integralNumber` boolean
    - `floatingPointNumber` boolean
    - `short` boolean
    - `int` boolean
    - `long` boolean
    - `float` boolean
    - `double` boolean
    - `bigDecimal` boolean
    - `bigInteger` boolean
    - `textual` boolean
    - `boolean` boolean
    - `null` boolean
    - `binary` boolean
  - `scheduleEnabled` boolean — Whether scheduled (unattended) exports are enabled for this template.
  - `scheduleFrequency` string — Schedule cadence: `daily`, `weekly`, `monthly`, or `custom`. Null when no schedule is configured.
  - `scheduleTime` string — Time of day the schedule runs, 24-hour `HH:mm`. Null when scheduleFrequency is `custom` or no schedule is configured.
  - `scheduleDayOfWeek` integer — Day of week the schedule runs: 1 = Sunday ... 7 = Saturday. Only set when scheduleFrequency=`weekly`.
  - `scheduleDayOfMonth` integer — Day of month (1-31) the schedule runs. Only set when scheduleFrequency=`monthly`.
  - `scheduleCron` string — Quartz cron expression (6-7 fields, not standard 5-field Unix cron) defining the schedule. Only set when scheduleFrequency=`custom`.
  - `scheduleTimezone` string — IANA timezone identifier the schedule runs in, e.g. `America/New_York`.
  - `scheduleDaysOfWeek` string — Comma-separated days of week the schedule runs: 1 = Sunday ... 7 = Saturday. Only set when scheduleFrequency=`weekly`.
  - `scheduleInterval` integer — Interval in hours between runs (1, 2, 3, 4, 6, 8 or 12 — divisors of 24). Only set when scheduleFrequency=`hourly`.
  - `lastExportAt` string, date-time
  - `nextExportAt` string, date-time
  - `metadata` JsonNode
    - `empty` boolean
    - `valueNode` boolean
    - `containerNode` boolean
    - `missingNode` boolean
    - `array` boolean
    - `object` boolean
    - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
    - `pojo` boolean
    - `number` boolean
    - `integralNumber` boolean
    - `floatingPointNumber` boolean
    - `short` boolean
    - `int` boolean
    - `long` boolean
    - `float` boolean
    - `double` boolean
    - `bigDecimal` boolean
    - `bigInteger` boolean
    - `textual` boolean
    - `boolean` boolean
    - `null` boolean
    - `binary` boolean
  - `jobType` string — Derived export trigger type for the Activity Center UI: `SCHEDULED` when a schedule is enabled, `MANUAL` otherwise. Not persisted by the data store.
  - `createdByName` string — Display name resolved from createdBy, when resolvable. Null if resolution failed or has not been attempted; callers should fall back to createdByEmail then createdBy in that case.
  - `createdByEmail` string — Email resolved from createdBy, when resolvable. Null if resolution failed or has not been attempted; used as the display fallback between createdByName and the raw createdBy id.
  - `bqExportEnabled` boolean
  - `bqTableName` string
  - `bqDataset` string

## Other responses

- `400` — The request supplies an unsupported status, an invalid CSV, or schedule fields that violate the frequency's rules; the error message states which field and why
- `401` — The request is missing a valid bearer token; re-authenticate and retry
- `403` — The authenticated caller lacks the update-template permission for this tenant
- `404` — No template with this id exists for the requesting tenant, or it belongs to a different tenant

---

[API](https://skmtc.net/certifyos/apis/certify-api-layer.md) · [All operations](https://skmtc.net/certifyos/apis/certify-api-layer/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/certifyos/certify-api-layer/revisions/563848e0ecc0/schema)
