---
title: "Search public image templates and optionally GIF templates"
method: GET
path: "/api/templates"
tags: ["templates"]
---

# Search public image templates and optionally GIF templates

`GET /api/templates`

Defaults to image templates for compatibility. Pass mediaType=gif or mediaType=all to intentionally request GIF catalog rows. Approved GIF templates can be rendered with the GIF generation API.

## Query parameters

- `query` string
- `q` string
- `tag` string
- `page` integer
- `pageSize` integer
- `sort` 'curated' | 'trending'
- `mode` 'lexical' | 'hybrid'
- `mediaType` 'image' | 'gif' | 'all'

## Response `200`

Template search results

- TemplateSearchResponse
  - `mediaType` 'image' | 'gif' | 'all'
  - `searchMode` 'lexical' | 'hybrid'
  - `fallbackApplied` boolean
  - `items` PublicTemplateMediaItem[], required
    - `id` string, required — Opaque public identity used for deduplication and exact detail lookup.
    - `sourceTemplateId` string, nullable, required — Stored source identity, preserved without slug normalization.
    - `variantOf` string, nullable
    - `slug` string, required — Canonical URL and publishing slug. Use this field, not id, with legacy publishing APIs.
    - `name` string, required
    - `description` string, required
    - `mediaType` 'image' | 'gif' — Present for explicit mediaType requests; omitted by legacy default image routes.
    - `imageUrl` string, required
    - `sourceUrl` string, required
    - `canonicalUrl` string, required
    - `detailUrl` string, required
    - `exampleImageUrl` string, nullable
    - `previewImageUrl` string
    - `posterImageUrl` string
    - `width` number, nullable, required
    - `height` number, nullable, required
    - `captionCount` integer, required
    - `boxCount` integer, required
    - `captions` MemeCaption[], required
      - `id` string, required
      - `text` string, required
      - `x` number, required
      - `y` number, required
      - `fontSize` number, required
      - `rotationDeg` number
      - `hidden` boolean
      - `locked` boolean
      - `boxWidthPct` number
      - `boxHeightPct` number
      - `paddingPct` number
      - `maxLines` integer
      - `lineHeight` number
      - `backgroundEnabled` boolean
      - `backgroundColor` string
      - `backgroundOpacity` number
      - `letterSpacingEm` number
      - `shadowStrength` number
      - `color` string
      - `stroke` string
      - `fontFamily` 'impact' | 'arial' | 'poster'
      - `textAlign` 'left' | 'center' | 'right'
      - `semanticRole` 'setup' | 'contrast' | 'punchline' | 'reaction' | 'label'
      - `preferredCase` 'uppercase' | 'sentence' | 'title' | 'preserve'
      - `exampleText` string
      - `recommendedWordsMin` integer
      - `recommendedWordsMax` integer
      - `recommendedCharsMin` integer
      - `recommendedCharsMax` integer
    - `tags` string[], required
    - `categories` string[]
    - `assetContentType` string
    - `animated` boolean
    - `durationMs` integer, nullable
    - `frameCount` integer, nullable
    - `assetBytes` integer, nullable
    - `qualityStatus` 'approved' | 'quarantined' | 'rejected' | 'pending'
  - `total` integer, required
  - `nextPage` integer, nullable, required
  - `page` integer, required
  - `pageSize` integer, required

## Other responses

- `429` — Rate limit exceeded

---

[API](https://skmtc.net/memesio/apis/memesio-api-contracts.md) · [All operations](https://skmtc.net/memesio/apis/memesio-api-contracts/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/memesio/memesio-api-contracts/revisions/826e6edbf294/schema)
