> ## Documentation Index
> Fetch the complete documentation index at: https://docs.infery.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# List templates

> GET /v1/workflows/templates

Ready-made workflows you can copy. Paginated and filterable; the list carries names and categories, not the definitions.


## OpenAPI

````yaml openapi.json GET /v1/workflows/templates
openapi: 3.0.0
info:
  title: Infery Gateway
  description: >-
    Infery Inference Gateway — OpenAI-compatible API for LLMs, embeddings,
    images, audio, and video
  version: '1.0'
  contact: {}
servers:
  - url: https://api.infery.ai
    description: Production
  - url: http://localhost:3001
    description: Local
security: []
tags: []
paths:
  /v1/workflows/templates:
    get:
      tags:
        - Workflows
      summary: List workflow templates (paginate + filter)
      description: >-
        The starter-workflow catalog. GLOBAL, not workspace-scoped: every key
        sees the same rows, none of them belong to anyone, and nothing here can
        be written through this API. Free, and it touches no workflow of yours.
        Hidden templates are excluded from this list and from `total`; they
        remain reachable by slug, which reports why. The rows carry no
        `definition` — fetch one by slug for that. Ordered by `created_at`,
        OLDEST first, so the page at a given offset is stable as new templates
        are added. The two filters combine as AND, and both are exact —
        `category` matches the whole value and `tag` matches one element of the
        tags array; neither does prefix or fuzzy matching.
      operationId: PipelineTemplatesController_list[0]
      parameters:
        - name: category
          required: false
          in: query
          description: >-
            Filter by exact category match. Templates with no category are
            excluded when this is set.
          schema:
            example: reporting
            type: string
        - name: tag
          required: false
          in: query
          description: Filter where the tags array contains this tag, matched in full.
          schema:
            example: documents
            type: string
        - name: limit
          required: false
          in: query
          description: >-
            Page size (1-100, default 20). A non-integer or out-of-range value
            is a 400, not a clamp.
          schema:
            example: 20
            type: string
        - name: offset
          required: false
          in: query
          description: >-
            Pagination offset (default 0). Must be a non-negative integer;
            anything else is a 400.
          schema:
            example: 0
            type: string
      responses:
        '200':
          description: One page of visible templates, oldest first.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateListResponseDto'
        '400':
          description: >-
            `limit` or `offset` is not an integer in range
            (`invalid_template_query`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '401':
          description: Unauthorized — invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
      security:
        - ApiKey: []
components:
  schemas:
    TemplateListResponseDto:
      type: object
      properties:
        items:
          description: >-
            One page of templates, oldest first. Hidden templates are excluded
            from the list entirely — they are only reachable by slug.
          type: array
          items:
            $ref: '#/components/schemas/TemplateSummaryDto'
        total:
          type: number
          description: >-
            Total templates matching the filters, counted with the same
            `unavailable_since IS NULL` exclusion as `items`.
          example: 12
        limit:
          type: number
          description: Page size applied (the request's `limit`, or 20).
          example: 20
        offset:
          type: number
          description: Offset applied (the request's `offset`, or 0).
          example: 0
      required:
        - items
        - total
        - limit
        - offset
    ErrorResponseDto:
      type: object
      properties:
        error:
          description: >-
            The error envelope. Every non-2xx response from this API has this
            shape, so a client can parse failures without branching on the
            endpoint.
          allOf:
            - $ref: '#/components/schemas/ErrorDetailDto'
      required:
        - error
    TemplateSummaryDto:
      type: object
      properties:
        slug:
          type: string
          description: >-
            Stable identifier, and the path segment for the detail route. Max
            120 characters.
          example: weekly-report
        title:
          type: string
          description: Display title. Max 200 characters.
          example: Weekly report
        description:
          type: string
          description: Catalog description. Always a string — the column is NOT NULL.
          example: Summarise a week of notes and render a PDF.
        category:
          type: string
          nullable: true
          description: >-
            Catalog category, or null when the template is uncategorised. The
            `category` filter matches this exactly.
          example: reporting
        tags:
          description: >-
            Free-form tags. The `tag` filter matches a template whose array
            CONTAINS the given tag.
          example:
            - documents
            - summarisation
          type: array
          items:
            type: string
        step_types_used:
          description: >-
            The step types the template's definition uses, denormalised at seed
            time for filtering and display.
          example:
            - model
            - transform
          type: array
          items:
            type: string
        thumbnail_url:
          type: string
          nullable: true
          description: Preview image URL, or null when the template has none.
          example: null
        created_at:
          type: string
          description: >-
            ISO-8601 creation timestamp. The list is ordered by this, OLDEST
            first.
          example: '2026-02-11T08:00:00.000Z'
      required:
        - slug
        - title
        - description
        - category
        - tags
        - step_types_used
        - thumbnail_url
        - created_at
    ErrorDetailDto:
      type: object
      properties:
        message:
          type: string
          example: Model not found
          description: Human-readable error message
        type:
          type: string
          example: invalid_request_error
          description: Error category
          enum:
            - invalid_request_error
            - authentication_error
            - permission_error
            - quota_exceeded
            - rate_limit_error
            - server_error
        code:
          type: string
          example: model_not_found
          nullable: true
          description: >-
            Stable machine-readable error code. Branch on this rather than on
            `message`, which is prose and may be reworded.
        param:
          type: string
          example: model
          nullable: true
          description: >-
            Name of the request parameter that triggered the error. `null` when
            the error is not attributable to one field.
        job_id:
          type: string
          example: job_1hR9xTPZqK4mVLc2nJ7fY5wB
          description: >-
            Handle to work that is ALREADY RUNNING AND ALREADY BILLED, present
            on the few errors that carry one. When it is here, this is not a
            failure to retry — retrying pays twice. Collect the result from `GET
            /v1/images/jobs/{job_id}`, which serves every durable media job
            regardless of modality.


            Two situations produce it. A media generation that outruns the
            gateway's wait answers `504` with `code: "job_timeout"` and keeps
            working. And `POST /v1/audio/speech` answers **500** with `code:
            "artifact_unreadable"` when the speech was generated and settled but
            could not be read back from storage — the audio exists and is paid
            for; only this response failed.


            Declared here rather than per-endpoint because the rule is about the
            FIELD, not the status: if this is present, there is a paid-for
            result to collect. It was undeclared until now, so a client
            generated from this document could not see the one field that
            recovers money already spent.
      required:
        - message
        - type
        - code
        - param
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: 'API key in format: Bearer inf_***'

````