---
title: "Start legacy two-step template upload with field suggestions"
method: POST
path: "/templates"
tags: ["Template"]
---

# Start legacy two-step template upload with field suggestions

`POST /templates`

Creates a template record with status `in-progress`, uploads the raw file to GCS as `template.csv`, and runs column-to-field suggestion matching against the file's header row, returning ranked mapping suggestions per column.

**When to use:** Use this as step 1 of the legacy two-step flow when you want to inspect and edit the suggested field mappings before approving. If the mapping is already known, use `POST /templates/single-step` instead, which does everything in one call. After this call you must call `PUT /templates/{id}` to confirm the column mappings and then `PUT /templates/{id}/approve` to finalize the template.

**How:** Send a `multipart/form-data` request with the required `tenant-id` header and fields: `name` (display name), `type` (`PRACTITIONER`, `FACILITY`, or `GROUP` - `GROUP` requires the tenant's `supportGroupRosters` configuration, otherwise 400), `description` (optional), and `file` - a roster-shaped CSV whose header row supplies the column names to match. Unlike the single-step endpoint, no `.csv` extension check is applied here; the file is parsed as CSV regardless of its name. Columns with a previously confirmed mapping in the tenant's column-mapping cache return that single high-confidence match; all other columns are fuzzy-matched against the system-field catalog.

**Returns:** A `TemplateUploadResponse` with `status` `in-progress` and a `data` object carrying the new template's `id`, the per-column suggestions (`fields`), the full mappable field catalog for the roster type (`allFields`), and entity-group hints (`entities`). The template is not yet usable for roster uploads until the confirm and approve steps complete.

## Headers

- `tenant-id` string, required

## Response `200`

The new template's ID plus per-column mapping suggestions and the full field catalog to review before confirming mappings.

- TemplateUploadResponse — Result of step 1 of the two-step template flow: the new template plus auto-suggested column mappings for review.
  - `status` string — Processing status of the new template. Always `in-progress` at this point in the flow; it becomes `success` only after `PUT /templates/{id}/approve` completes.
  - `data` TemplateData — Suggestion payload for a newly created two-step template.
    - `id` string — Server-generated ID of the template record just created. Use it in the follow-up `PUT /templates/{id}` and `PUT /templates/{id}/approve` calls.
    - `name` string — Display name the template was created with.
    - `entities` string[] — Entity-group hints for the template-builder UI, ordered for display. Group-roster templates expose Group-related entities only.
    - `allFields` Field[] — The full catalog of mappable Certify system fields for the template's roster type, so the consumer can offer alternatives beyond the auto-suggested matches.
      - `name` string — CSV column header this mapping applies to, exactly as it appears in the roster file.
      - `mappedKey` string — Key of the Certify system field this column maps to, from the field catalog returned by `GET /templates/fields`. The sentinel `[skipped]` marks a column the user explicitly chose not to map: skipped columns persist in the template/mappings CSVs but are excluded from the generated validation schema.
      - `mappedEntity` string — Entity that owns the mapped attribute (for example `practitioner` or `location`). When set, `mappedKey` is accepted as-is instead of being validated against the system-field catalog.
      - `entityGroup` string — Group label linking columns that belong to the same repeating entity instance (a multiple-value group), so related columns are ingested together.
      - `isRequired` boolean — Whether every roster row must supply a value for this column; drives the `required` constraint in the generated validation schema.
      - `isStaticField` boolean — Catalog metadata: whether the mapped system field is a static (fixed-value) field rather than one populated from roster data.
      - `isSingleSelect` boolean — Catalog metadata: whether the mapped system field accepts a single value from a fixed option list.
      - `validationRegex` string — Regular expression applied to this column's values during roster validation. Rows whose values do not match are rejected.
      - `description` string — Human-readable description of the mapped system field, from the field catalog.
      - `enum` string[] — Allowed values for enum-type system fields; roster values outside this list fail validation. Absent for free-form fields.
      - `separator` string — Literal separator character used to split a single cell value into multiple tokens for multi-value attributes. Blank or absent defaults to a comma at schema-generation time.
      - `singleSelect` boolean
      - `skipped` boolean
    - `fields` FieldSuggestion[] — Per-column mapping suggestions for the uploaded file, one entry per CSV header.
      - `name` string — CSV column header the suggestions apply to, exactly as it appears in the uploaded file.
      - `suggestedMatches` Field[] — Candidate system-field mappings for this column, best match first. A column with a previously confirmed mapping in the tenant's column-mapping cache returns that single high-confidence match; otherwise candidates come from fuzzy-matching the header against the system-field catalog. Empty when nothing scored above the match threshold.
        - `name` string — CSV column header this mapping applies to, exactly as it appears in the roster file.
        - `mappedKey` string — Key of the Certify system field this column maps to, from the field catalog returned by `GET /templates/fields`. The sentinel `[skipped]` marks a column the user explicitly chose not to map: skipped columns persist in the template/mappings CSVs but are excluded from the generated validation schema.
        - `mappedEntity` string — Entity that owns the mapped attribute (for example `practitioner` or `location`). When set, `mappedKey` is accepted as-is instead of being validated against the system-field catalog.
        - `entityGroup` string — Group label linking columns that belong to the same repeating entity instance (a multiple-value group), so related columns are ingested together.
        - `isRequired` boolean — Whether every roster row must supply a value for this column; drives the `required` constraint in the generated validation schema.
        - `isStaticField` boolean — Catalog metadata: whether the mapped system field is a static (fixed-value) field rather than one populated from roster data.
        - `isSingleSelect` boolean — Catalog metadata: whether the mapped system field accepts a single value from a fixed option list.
        - `validationRegex` string — Regular expression applied to this column's values during roster validation. Rows whose values do not match are rejected.
        - `description` string — Human-readable description of the mapped system field, from the field catalog.
        - `enum` string[] — Allowed values for enum-type system fields; roster values outside this list fail validation. Absent for free-form fields.
        - `separator` string — Literal separator character used to split a single cell value into multiple tokens for multi-value attributes. Blank or absent defaults to a comma at schema-generation time.
        - `singleSelect` boolean
        - `skipped` boolean

## Other responses

- `400` — The requested `GROUP` type is not enabled for the tenant, or the request is otherwise malformed. The `errors` list carries the cause; correct the request and retry.
- `401` — Authentication required - supply a valid bearer token.
- `403` — The authenticated user lacks the `CREATE_TEMPLATE` permission.
- `500` — Unexpected server-side failure (for example a GCS or data-layer outage, or an unparseable file). Safe to retry once the underlying issue clears; a retry creates a new template record.

---

[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)
