---
title: "List Experiment Templates"
method: GET
path: "/experiment_templates"
tags: ["experiment_templates"]
---

# List Experiment Templates

`GET /experiment_templates`

List a project's experiment templates.

``project_id`` is **required**. Protocols are project-scoped: every project
holds its own copies of the built-in catalog, so an organization-wide list
returns the same protocol once per project rather than a meaningful catalog.
This endpoint used to union the org's unscoped rows with the system
organization's; both of those sources are gone in the contract phase, so
rather than silently returning N copies of everything it now rejects the
call. The response is lightweight by default:
large JSONB columns
(``protocol_config``, ``parameters_schema``, ``time_series_spec``,
``metrics_spec``, ``plot_options``) and the ``source_protocol`` text are
omitted unless explicitly requested via ``?include=``. Fetch the full
template via ``GET /{template_id}`` when the user opens one.

Parameters
----------
limit : int | None, optional
    Page size (1-100). When omitted, one page of up to PostgREST's
    ``max_rows`` is returned; compare ``count`` against ``total`` to
    detect that there is more.
offset : int | None, optional
    Number of records to skip before the page starts.
include : str | None, optional
    Comma-separated list of heavy columns to include in the response.
    Supported values: ``protocol_config``, ``parameters_schema``,
    ``time_series_spec``, ``metrics_spec``, ``plot_options``,
    ``source_protocol``. Unknown names are silently ignored.
project_id : str
    Project whose protocols to return. Required — see above.
name : str | None, optional
    Text filter on the protocol name, per the field's policy in
    ``_PROTOCOL_FILTERS``: ``ilike.%rpt%`` for a partial match,
    ``eq.RPT`` for an exact one. A bare value is equality.
created_by_email : str | None, optional
    Text filter on the creator's email, same operator syntax as ``name``.
created_at, updated_at : str | None, optional
    Date filters: ``gte.value`` / ``lte.value`` etc. Use the ``_gt`` /
    ``_lt`` variants together for a between query.
order_by : str, optional
    Column to sort by. Defaults to ``created_at``.
order : str, optional
    Sort direction. Defaults to ``desc``.

Returns
-------
ExperimentTemplateListResponse
    ``items``, ``count`` (rows in this response) and ``total`` (every
    protocol matching the filters). ``count < total`` means the result was
    truncated — page through with ``limit`` / ``offset`` to get the rest.

Raises
------
BadRequestError
    If ``project_id`` is omitted, or a filter value violates its field
    policy. An unsupported ``order_by`` / ``order`` is a 422 from FastAPI.

## Query parameters

- `limit` integer, nullable
- `offset` integer, nullable
- `include` string, nullable
- `q` string, nullable — Free-text search on template name plus prefix full-text match, matching the global search.
- `project_id` string, nullable
- `name` string, nullable
- `description` string, nullable
- `created_by_email` string, nullable
- `protocol_group_id` string, nullable
- `created_at` string, nullable
- `created_at_gt` string, nullable
- `created_at_lt` string, nullable
- `updated_at` string, nullable
- `updated_at_gt` string, nullable
- `updated_at_lt` string, nullable
- `order_by` 'name' | 'created_at' | 'updated_at'
- `order` 'asc' | 'desc'

## Response `200`

Successful Response

- ExperimentTemplateListResponse — Paginated list of experiment templates.
  - `items` ExperimentTemplate[], required
    - `id` string, nullable — Unique identifier for the template
    - `name` string, required — Name of the template
    - `description` string, nullable — Description of the template
    - `description_template` string, nullable — Template string for generating user-facing descriptions with {{param}} placeholders
    - `protocol_config` object, nullable — Protocol configuration (UCP format). Omitted from list responses by default; opt in via ``?include=protocol_config``.
    - `parameters_schema` object, nullable — Parameters schema defining what parameters this template accepts. Omitted from list responses by default; opt in via ``?include=parameters_schema``.
    - `organization_id` string, required — ID of the organization that owns this template
    - `created_at` string, nullable — When the template was created
    - `updated_at` string, nullable — When the template was last updated
    - `plot_options` object — Plot configuration options organized by plot type (time_series, metrics)
    - `time_series_spec` object — Specification mapping time-series keys to calculation rules.
    - `metrics_spec` object — Specification mapping metric names to calculation rules.
    - `source_protocol` string, nullable — Original protocol text as entered by the user
    - `created_by` string, nullable — User ID of the user who created this template
    - `created_by_email` string, nullable — Email of the user who created this template
    - `project_id` string, nullable — ID of the project that owns this protocol. Every protocol reachable through the API is project-scoped; None only on unmigrated rows.
    - `protocol_group_id` string, nullable — ID of the protocol group this protocol belongs to. Protocols sharing a group are related. None means ungrouped. The group is always in the same project as the protocol.
  - `count` integer, required
  - `total` integer, required

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/ionworks/apis/fastapi.md) · [All operations](https://skmtc.dev/ionworks/apis/fastapi/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/ionworks/fastapi/revisions/7337a3cbdaf2/schema)
