tiero

API reference

Every endpoint under /api/v1, with auth, parameters and responses.

Overview

Every endpoint lives under https://tiero.io/api/v1/. This page is generated from the same document served at /api/v1/openapi.json (OpenAPI 3.1), which you can feed to any client generator.

  • Auth lists what each endpoint accepts. None means a public read; send an API key (Authorization: Bearer tiero_sk_...) for writes. Sessions are for tiero.io itself.
  • Caching. Anonymous reads of public resources return Cache-Control: public, max-age=60 and Access-Control-Allow-Origin: *. Anything sent with a key or cookie is private, no-store.
  • Errors share one shape, ErrorDTO. Pages are { items, nextCursor }: pass nextCursor back as cursor.

Health

Service health.

GET /api/v1/health

Check API health

  • None

Return a lightweight process health signal. No authentication is required.

Responses

  • 200 Success object
  • 500 internal_error
  • 503 service_unavailable

Account

Identity and API keys.

GET /api/v1/me

Read the current identity

  • Session
  • API key
  • Embed token

Session and API key callers receive SessionUser. Embed tokens receive only id, username, isPremium and scopes.

Parameters

  • X-Tiero-Embed string header

    Required when using an embed token; must equal its embed ID. Omit for session or API key authentication.

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/keys

List API keys

  • Session

List the session owner’s unrevoked keys, including expired keys. Tokens are never returned.

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/keys

Create an API key

  • Session

Create one of at most ten active keys. The token is shown only in this response. JSON body limit: 64 KiB.

Body KeyCreate

  • name string required
  • scopes 'catalogs:write' | 'media:write' | 'lists:read' | 'lists:write'[] required
  • expiresInDays 30 | 90 | 365 | null

Responses

  • 201 Success object
  • 400 bad_request or invalid_json
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 409 conflict: ten active keys already exist
  • 413 payload_too_large
  • 422 validation_failed
  • 500 internal_error
  • 503 service_unavailable
DELETE /api/v1/keys/{id}

Revoke an API key

  • Session

Revoke an unrevoked key owned by the session user.

Parameters

  • id string path required

Responses

  • 204 Completed; no response body.
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found: key is missing, revoked or owned by another user
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/oauth/grants

List connected apps

  • Session

List the session user’s active OAuth grants. The unavailable flag signals an absent MCP service.

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 500 internal_error
  • 503 service_unavailable
DELETE /api/v1/oauth/grants/{id}

Disconnect an app

  • Session

Revoke one OAuth grant owned by the session user. Session writes require a matching Origin.

Parameters

  • id string path required

Responses

  • 204 Completed; no response body.
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 grant_not_found
  • 500 internal_error
  • 503 service_unavailable

Media

Upload and manage images.

POST /api/v1/media

Upload an image

  • Session
  • API key (media:write)

Upload multipart file, up to 5 MiB. PNG, JPEG, WebP, GIF and AVIF inputs must be 16 to 8000 pixels per side. Images are sanitized to WebP; existing owned content deduplicates with status 200. Required scope: media:write for API keys. Sessions do not require scopes.

Body object

  • file string required

Responses

  • 400 bad_request or invalid_json
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 409 media_removed or media_total_limit
  • 413 payload_too_large
  • 415 unsupported_media_type
  • 422 validation_failed
  • 429 rate_limited or daily_quota; retry after 60 seconds
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/media/{id}

Read owned media

  • Session
  • API key (media:write)

Return media owned by the authenticated user. This endpoint is private and does not enable public CORS. Required scope: media:write for API keys. Sessions do not require scopes.

Parameters

  • id string path required

Responses

  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 500 internal_error
  • 503 service_unavailable
DELETE /api/v1/media/{id}

Delete owned media

  • Session
  • API key (media:write)

Remove owned media and purge its cached image. A reference from a live catalog item prevents deletion. Required scope: media:write for API keys. Sessions do not require scopes.

Parameters

  • id string path required

Responses

  • 204 Completed; no response body.
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 409 media_in_use or media_removed
  • 429 rate_limited
  • 500 internal_error
  • 503 service_unavailable

Catalogs

Publish and read catalogs and items.

GET /api/v1/catalogs

Explore public catalogs

  • None

Search publicly visible catalogs. Search has at most eight terms. Unknown or repeated query parameters are rejected. Anonymous public reads return Cache-Control: public, max-age=60 and Access-Control-Allow-Origin: *. Credentialed or non-public reads return private, no-store. Responses vary on Cookie and Authorization. Errors are not publicly cached; anonymous errors include Access-Control-Allow-Origin: * on catalog detail, consensus and list read routes.

Parameters

  • q string query
  • tag string query
  • game string query
  • owner string query
  • cursor string query

    Opaque cursor from nextCursor; omit for the first page.

  • limit integer query

Responses

  • 400 bad_request: invalid query or cursor
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/catalogs/{owner}/{slug}

Read a catalog

  • None

Public and unlisted catalogs are readable anonymously. Private catalogs require an owner session or owner API key with any scope. Old usernames resolve through aliases. Query parameters are rejected. Anonymous public reads return Cache-Control: public, max-age=60 and Access-Control-Allow-Origin: *. Credentialed or non-public reads return private, no-store. Responses vary on Cookie and Authorization. Errors are not publicly cached; anonymous errors include Access-Control-Allow-Origin: * on catalog detail, consensus and list read routes.

Parameters

  • owner string path required
  • slug string path required
  • If-None-Match string header

    Optional cached validator; accepts comma-separated validators, weak validators and *.

Responses

  • 200 Success CatalogDTO
  • 304 Validator matched; no response body.
  • 400 bad_request
  • 404 not_found: missing or inaccessible catalog
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/catalogs/{owner}/{slug}/items

Read catalog items

  • None

Public and unlisted catalogs are readable anonymously. Private catalogs require an owner session or owner API key with any scope. Old usernames resolve through aliases. Returns active catalog entries in sort and item ID order. Anonymous public reads return Cache-Control: public, max-age=60 and Access-Control-Allow-Origin: *. Credentialed or non-public reads return private, no-store. Responses vary on Cookie and Authorization. Errors are not publicly cached; anonymous errors include Access-Control-Allow-Origin: * on catalog detail, consensus and list read routes.

Parameters

  • owner string path required
  • slug string path required
  • q string query
  • group string query
  • cursor string query

    Opaque cursor from nextCursor; omit for the first page.

  • limit integer query

Responses

  • 400 bad_request: invalid query or cursor
  • 404 not_found
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/catalogs/{owner}/{slug}/items/resolve

Resolve catalog item IDs

  • None

Public and unlisted catalogs are readable anonymously. Private catalogs require an owner session or owner API key with any scope. Old usernames resolve through aliases. Resolve 1 to 500 IDs, including removed entries with status. Duplicate IDs are collapsed; unknown IDs appear separately. JSON body limit: 64 KiB. Responses are private, no-store and vary on Cookie and Authorization.

Parameters

  • owner string path required
  • slug string path required

Body ItemsResolve

  • ids string[] required

Responses

  • 200 Success object
  • 400 bad_request or invalid_json
  • 404 not_found
  • 413 payload_too_large
  • 422 validation_failed
  • 500 internal_error
  • 503 service_unavailable
PUT /api/v1/catalogs/{slug}

Create or replace a catalog

  • Session
  • API key (catalogs:write)

Upsert the owner’s catalog from CatalogSpecV1. Path and body slugs must match. If-None-Match: * makes this create-only and cannot accompany If-Match. If-Match checks the catalog revision. Set rightsAck=1 to acknowledge media rights. JSON body limit: 1 MiB. Required scope: catalogs:write for API keys. Sessions do not require scopes.

Parameters

  • slug string path required
  • rightsAck '1' query

    Acknowledge rights to included media.

  • If-Match string header

    Optional catalog revision validator, for example "r3".

  • If-None-Match '*' header

    Create only; fail if the catalog already exists.

Body CatalogPut

  • spec 'tiero-catalog/1' required
  • slug string required
  • title string required
  • description string
  • game string
  • tags string[]
  • visibility 'public' | 'unlisted' | 'private'
  • showNames boolean
  • license object
  • defaultTiers object[]
  • groups object[]
  • branding object
  • items object[] required

Responses

  • 400 bad_request, invalid_json or branding_domain_unverified
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 412 catalog_conflict or catalog_exists; revision mismatch or create-only conflict
  • 413 payload_too_large
  • 422 validation_failed
  • 429 rate_limited or daily_quota; retry after 60 seconds
  • 500 internal_error
  • 503 service_unavailable
PATCH /api/v1/catalogs/{slug}

Edit catalog metadata

  • Session
  • API key (catalogs:write)

Update at least one of title, description, visibility and tags. This bumps rev. Optional If-Match guards the current revision. JSON body limit: 64 KiB. Required scope: catalogs:write for API keys. Sessions do not require scopes.

Parameters

  • slug string path required
  • If-Match string header

    Optional catalog revision validator, for example "r3".

Body CatalogPatch

  • title string
  • description string
  • tags string[]
  • visibility 'public' | 'unlisted' | 'private'

Responses

  • 200 Success object
  • 400 bad_request or invalid_json
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 412 catalog_conflict
  • 413 payload_too_large
  • 422 validation_failed
  • 429 rate_limited or daily_quota; retry after 60 seconds
  • 500 internal_error
  • 503 service_unavailable
DELETE /api/v1/catalogs/{slug}

Delete a catalog

  • Session
  • API key (catalogs:write)

Soft-delete the owner’s catalog. Referencing lists become non-public through effective visibility. Required scope: catalogs:write for API keys. Sessions do not require scopes.

Parameters

  • slug string path required

Responses

  • 204 Completed; no response body.
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 412 catalog_conflict
  • 429 rate_limited
  • 500 internal_error
  • 503 service_unavailable

Consensus

Aggregated public tier boards.

GET /api/v1/catalogs/{owner}/{slug}/consensus

Read a catalog consensus

  • None

Public and unlisted catalogs are readable anonymously. Private catalogs require an owner session or owner API key with any scope. Old usernames resolve through aliases. A missing aggregate returns consensus_not_ready with details.listCount. Anonymous public reads return Cache-Control: public, max-age=60 and Access-Control-Allow-Origin: *. Credentialed or non-public reads return private, no-store. Responses vary on Cookie and Authorization. Errors are not publicly cached; anonymous errors include Access-Control-Allow-Origin: * on catalog detail, consensus and list read routes.

Parameters

  • owner string path required
  • slug string path required
  • If-None-Match string header

    Optional cached validator; accepts comma-separated validators, weak validators and *.

Responses

  • 200 Success ConsensusDTO
  • 304 Validator matched; no response body.
  • 400 bad_request
  • 404 not_found or consensus_not_ready; details.listCount reports eligible lists
  • 500 internal_error
  • 503 service_unavailable

Lists

Create, read and manage tier lists.

GET /api/v1/lists

Browse public lists

  • None

List publicly visible lists in recent or top order. Unknown and repeated query parameters are rejected. Anonymous public reads return Cache-Control: public, max-age=60 and Access-Control-Allow-Origin: *. Credentialed or non-public reads return private, no-store. Responses vary on Cookie and Authorization. Errors are not publicly cached; anonymous errors include Access-Control-Allow-Origin: * on catalog detail, consensus and list read routes.

Parameters

  • catalog string query
  • owner string query
  • embed string query
  • sort 'recent' | 'top' query
  • cursor string query

    Opaque cursor from nextCursor; omit for the first page.

  • limit integer query

Responses

  • 400 bad_request: invalid query or cursor
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/lists

Create a list

  • Session
  • API key (lists:write)
  • Embed token (lists:write)

Create a tier list from a catalog, using active item IDs. JSON body limit: 192 KiB. Visibility may be downgraded and reported in warnings. Embed writes require a builder embed with a premium owner; create, update and copy are restricted to its allowed catalogs. Non-public access, update and deletion are restricted to lists created by the same user in the same embed. Required scope: lists:write for API keys and embed tokens. Sessions do not require scopes.

Parameters

  • X-Tiero-Embed string header

    Required when using an embed token; must equal its embed ID. Omit for session or API key authentication.

Body ListCreate

  • catalog string required
  • title string required
  • description string
  • visibility 'public' | 'unlisted' | 'private'
  • schemaVersion 1 required
  • board object required
  • pool string[]

Responses

  • 201 Success object
  • 400 bad_request or invalid_json
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found: inaccessible catalog
  • 413 payload_too_large
  • 422 validation_failed
  • 429 rate_limited or daily_quota; retry after 60 seconds
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/lists/{id}

Read a list

  • None

Public and unlisted lists are readable anonymously. Private lists require an owner session, API key with lists:read or embed token with lists:read:own. Embed tokens can access non-public lists only when the user owns them and they originated in the same embed. Query parameters are rejected. Anonymous public reads return Cache-Control: public, max-age=60 and Access-Control-Allow-Origin: *. Credentialed or non-public reads return private, no-store. Responses vary on Cookie and Authorization. Errors are not publicly cached; anonymous errors include Access-Control-Allow-Origin: * on catalog detail, consensus and list read routes.

Parameters

  • id string path required

Responses

  • 400 bad_request
  • 403 embed_restricted
  • 404 not_found
  • 500 internal_error
  • 503 service_unavailable
PUT /api/v1/lists/{id}

Replace a list

  • Session
  • API key (lists:write)
  • Embed token (lists:write)

Replace the owner’s list metadata and placements. If-Match is required and checks the list revision; a conflict returns 412 revision_conflict. The catalog cannot change. JSON body limit: 192 KiB. Embed writes require a builder embed with a premium owner; create, update and copy are restricted to its allowed catalogs. Non-public access, update and deletion are restricted to lists created by the same user in the same embed. Required scope: lists:write for API keys and embed tokens. Sessions do not require scopes.

Parameters

  • id string path required
  • If-Match string header required

    Required list revision. Accepts 3, "3" or W/"3"; catalog-style "r3" is invalid.

  • X-Tiero-Embed string header

    Required when using an embed token; must equal its embed ID. Omit for session or API key authentication.

Body ListUpdate

  • catalog string
  • title string required
  • description string
  • visibility 'public' | 'unlisted' | 'private'
  • schemaVersion 1 required
  • board object required
  • pool string[]

Responses

  • 200 Success object
  • 400 bad_request or invalid_json
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 412 revision_conflict
  • 413 payload_too_large
  • 422 validation_failed
  • 428 precondition_required: If-Match is required
  • 429 rate_limited or daily_quota; retry after 60 seconds
  • 500 internal_error
  • 503 service_unavailable
DELETE /api/v1/lists/{id}

Delete a list

  • Session
  • API key (lists:write)
  • Embed token (lists:write)

Soft-delete the owner’s list. Embed writes require a builder embed with a premium owner; create, update and copy are restricted to its allowed catalogs. Non-public access, update and deletion are restricted to lists created by the same user in the same embed. Required scope: lists:write for API keys and embed tokens. Sessions do not require scopes.

Parameters

  • id string path required
  • X-Tiero-Embed string header

    Required when using an embed token; must equal its embed ID. Omit for session or API key authentication.

Responses

  • 204 Completed; no response body.
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 412 revision_conflict
  • 429 rate_limited
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/lists/{id}/viewer

Read list viewer state

  • Session
  • Embed token (lists:read:own)

Read whether the current viewer liked or owns a list. Owners also receive the unranked item pool. API keys are not accepted. Query parameters are rejected. Embed access is restricted to the same user and embed for non-public lists. Required scope: lists:read:own for embed tokens. Sessions do not require scopes.

Parameters

  • id string path required
  • X-Tiero-Embed string header

    Required when using an embed token; must equal its embed ID. Omit for session or API key authentication.

Responses

  • 400 bad_request
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/lists/{id}/copy

Copy a list

  • Session
  • API key (lists:write)
  • Embed token (lists:write)

Copy a publicly visible or owned list, retaining active items only. The optional body overrides title, description or visibility. Defaults to unlisted. An empty body is allowed. JSON body limit: 192 KiB. Embed writes require a builder embed with a premium owner; create, update and copy are restricted to its allowed catalogs. Non-public access, update and deletion are restricted to lists created by the same user in the same embed. Required scope: lists:write for API keys and embed tokens. Sessions do not require scopes.

Parameters

  • id string path required
  • X-Tiero-Embed string header

    Required when using an embed token; must equal its embed ID. Omit for session or API key authentication.

Body ListCopy

  • title string
  • description string
  • visibility 'public' | 'unlisted' | 'private'

Responses

  • 201 Success object
  • 400 bad_request or invalid_json
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 413 payload_too_large
  • 422 validation_failed
  • 429 rate_limited or daily_quota; retry after 60 seconds
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/lists/{id}/like

Like a list

  • Session
  • Embed token (likes:write)

Idempotently set the viewer’s like state. Requires a session or builder embed token; API keys are not accepted. Required scope: likes:write for embed tokens. Sessions do not require scopes.

Parameters

  • id string path required
  • X-Tiero-Embed string header

    Required when using an embed token; must equal its embed ID. Omit for session or API key authentication.

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 429 rate_limited or daily_quota
  • 500 internal_error
  • 503 service_unavailable
DELETE /api/v1/lists/{id}/like

Remove a list like

  • Session
  • Embed token (likes:write)

Idempotently set the viewer’s like state. Requires a session or builder embed token; API keys are not accepted. Required scope: likes:write for embed tokens. Sessions do not require scopes.

Parameters

  • id string path required
  • X-Tiero-Embed string header

    Required when using an embed token; must equal its embed ID. Omit for session or API key authentication.

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 429 rate_limited or daily_quota
  • 500 internal_error
  • 503 service_unavailable

Domains

Verify provider domains.

GET /api/v1/domains

List provider domains

  • Session

List the session owner’s branding domains and verification instructions.

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/domains

Register a provider domain

  • Session

Register a public hostname for DNS TXT or well-known verification. At most twenty domains per owner. JSON body limit: 4 KiB.

Body DomainCreate

  • domain string required

Responses

  • 400 bad_request or invalid_json
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 409 conflict: duplicate domain or domain limit
  • 413 payload_too_large
  • 422 validation_failed
  • 429 rate_limited or daily_quota; retry after 60 seconds
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/domains/{id}/verify

Verify a provider domain

  • Session

Check the owner’s domain using DNS TXT and well-known file verification. Failed verification returns verified=false with status 200.

Parameters

  • id string path required

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 429 rate_limited
  • 500 internal_error
  • 503 service_unavailable
DELETE /api/v1/domains/{id}

Delete a provider domain

  • Session

Remove an owned domain and invalidate affected catalog branding.

Parameters

  • id string path required

Responses

  • 204 Completed; no response body.
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 500 internal_error
  • 503 service_unavailable

Reports

Report content for moderation.

POST /api/v1/reports

Report content or a user

  • Session
  • Embed token (reports:write)

Report a catalog, item, media, list or user. The reporter cannot own the target or report it twice. Embed writes require a builder embed with a premium owner. JSON body limit: 4 KiB. Required scope: reports:write for embed tokens. Sessions do not require scopes.

Parameters

  • X-Tiero-Embed string header

    Required when using an embed token; must equal its embed ID. Omit for session or API key authentication.

Body Report

  • targetType 'catalog' | 'item' | 'media' | 'list' | 'user' required
  • targetId string required
  • reason 'spam' | 'sexual' | 'hate' | 'harassment' | 'violence' | 'copyright' | 'impersonation' | 'other' required
  • note string | null

Responses

  • 201 Success object
  • 400 bad_request or invalid_json
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 409 already_reported or moderation_conflict
  • 413 payload_too_large
  • 422 validation_failed
  • 429 rate_limited or daily_quota; retry after 60 seconds
  • 500 internal_error
  • 503 service_unavailable

DMCA

Copyright notices and counter notices.

POST /api/v1/dmca

Submit a DMCA notice

  • None

Submit a copyright notice after Turnstile verification. JSON body limit: 1 MiB. A committed notice can return emailFailed=true when notification delivery fails.

Body DmcaNotice

  • complainantName string required
  • complainantOrg string | null
  • complainantEmail string required
  • complainantAddress string required
  • complainantPhone string required
  • workDescription string required
  • urls string | string[] required

    One to fifty URLs, as an array or newline-separated string.

  • goodFaith true required
  • accuracyPerjury true required
  • signature string required
  • turnstileToken string required

    Required valid Turnstile verification token.

Responses

  • 201 Success object
  • 400 bad_request, invalid_json or validation_failed
  • 413 payload_too_large
  • 429 daily_quota
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/dmca/{noticeId}/counter-notice

Submit a DMCA counter notice

  • Session

Submit a counter notice for an actioned notice that affects the session user’s content. Requires Turnstile. JSON body limit: 1 MiB.

Parameters

  • noticeId string path required

Body DmcaCounterNotice

  • fullName string required
  • address string required
  • phone string required
  • statement string required
  • mistakePerjury true required
  • consentJurisdiction true required
  • signature string required
  • turnstileToken string required

    Required valid Turnstile verification token.

Responses

  • 201 Success object
  • 400 bad_request, invalid_json or validation_failed
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 409 conflict: a counter notice is already open
  • 413 payload_too_large
  • 500 internal_error
  • 503 service_unavailable

Embeds

Configure embeds and manage connections.

GET /api/v1/embeds

List embed configurations

  • Session

Requires the owner’s session and an active premium entitlement. API keys and embed tokens cannot manage embed configuration.

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/embeds

Create an embed configuration

  • Session

Requires the owner’s session and an active premium entitlement. API keys and embed tokens cannot manage embed configuration. At most twenty embeds. Origins must be allowed HTTPS origins, wildcard hosts or localhost development origins. Catalog references must be owned or publicly accessible. A listUrlTemplate must use an allowed origin and include {id}. JSON body limit: 64 KiB.

Body EmbedConfig

  • name string required
  • mode 'builder' | 'board'
  • allowedOrigins string[] required
  • catalogs array | null
  • theme object
  • listUrlTemplate string | null

Responses

  • 400 bad_request or invalid_json
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 409 conflict: embed limit
  • 413 payload_too_large
  • 422 validation_failed
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/embeds/{id}

Read an embed configuration

  • Session

Requires the owner’s session and an active premium entitlement. API keys and embed tokens cannot manage embed configuration.

Parameters

  • id string path required

Responses

  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 500 internal_error
  • 503 service_unavailable
PATCH /api/v1/embeds/{id}

Edit an embed configuration

  • Session

Requires the owner’s session and an active premium entitlement. API keys and embed tokens cannot manage embed configuration. Partially update configuration, including disabled. JSON body limit: 64 KiB.

Parameters

  • id string path required

Body object

  • name string
  • mode 'builder' | 'board'
  • allowedOrigins string[]
  • catalogs array | null
  • theme object
  • listUrlTemplate string | null
  • disabled boolean

Responses

  • 400 bad_request or invalid_json
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 409 conflict: embed changed concurrently
  • 413 payload_too_large
  • 422 validation_failed
  • 500 internal_error
  • 503 service_unavailable
DELETE /api/v1/embeds/{id}

Delete an embed configuration

  • Session

Requires the owner’s session and an active premium entitlement. API keys and embed tokens cannot manage embed configuration.

Parameters

  • id string path required

Responses

  • 204 Completed; no response body.
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/embed/token

Exchange an embed grant for a token

  • None

Redeem a one-time code with its PKCE verifier and embed ID. No session is required. Tokens expire after ninety days or thirty days idle. Use Authorization: Bearer tiero_et_... and X-Tiero-Embed on later requests. JSON body limit: 2 KiB.

Body EmbedToken

  • embedId string required
  • verifier string required
  • code string required

Responses

  • 201 Success object
  • 400 bad_request or invalid_json
  • 403 forbidden, account_suspended or embed_restricted
  • 404 grant_not_found
  • 410 grant_used or grant_expired
  • 413 payload_too_large
  • 429 rate_limited
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/embed/connections

List connected sites

  • Session

List the session user’s active embed tokens. Expired, idle and revoked connections are excluded.

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 500 internal_error
  • 503 service_unavailable
DELETE /api/v1/embed/connections/{id}

Disconnect a site

  • Session

Revoke one active embed connection owned by the session user.

Parameters

  • id string path required

Responses

  • 204 Completed; no response body.
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 500 internal_error
  • 503 service_unavailable

Admin

Staff-only moderation and operations.

GET /api/v1/admin/entitlements

List entitlements and audit

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Return current entitlements and recent audit entries.

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/admin/entitlements

Grant or extend premium

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Grant premium to an existing username. endsAt must be a future timestamp or null for no expiry. JSON body limit: 8 KiB.

Body object

  • username string required
  • endsAt string | null
  • note string | null

Responses

  • 200 Success object
  • 400 bad_request, invalid_json or validation_failed
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 413 payload_too_large
  • 500 internal_error
  • 503 service_unavailable
DELETE /api/v1/admin/entitlements/{userId}

Revoke premium

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Revoke an entitlement and schedule synchronization. Optional JSON body limit: 8 KiB.

Parameters

  • userId string path required

Body object

  • note string | null

Responses

  • 204 Completed; no response body.
  • 400 bad_request, invalid_json or validation_failed
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 413 payload_too_large
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/admin/reports

Read the report queue

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Return up to fifty target groups with reasons, notes and active holds.

Parameters

  • status 'open' | 'resolved' query
  • cursor string query

Responses

  • 200 Success object
  • 400 bad_request: invalid status or cursor
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/admin/reports/resolve

Resolve reports for a target

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Resolve all open reports on a target and optionally add a hidden or removed hold. JSON body limit: 4 KiB.

Body object

  • targetType 'catalog' | 'item' | 'media' | 'list' | 'user' required
  • targetId string required
  • resolution 'dismissed' | 'actioned' required
  • hold 'hidden' | 'removed'
  • note string | null

Responses

  • 200 Success object
  • 400 bad_request, invalid_json or validation_failed
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 409 moderation_conflict
  • 413 payload_too_large
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/admin/holds/{id}/release

Release a moderation hold

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Release a non-DMCA hold. DMCA holds require restoring the notice. Optional JSON body limit: 4 KiB.

Parameters

  • id string path required

Body object

  • reason string | null

Responses

  • 200 Success object
  • 400 bad_request, invalid_json or validation_failed
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 409 conflict or moderation_conflict
  • 413 payload_too_large
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/admin/dmca

Read the DMCA queue

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Return up to fifty notices, their targets and associated counter notices.

Parameters

  • status 'received' | 'actioned' | 'rejected' | 'withdrawn' query
  • cursor string query

Responses

  • 200 Success object
  • 400 bad_request: invalid status or cursor
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/admin/dmca/{id}/action

Action a DMCA notice

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Update the notice state. Optional JSON body limit: 8 KiB.

Parameters

  • id string path required

Body object

  • note string | null

Responses

  • 200 Success object
  • 400 bad_request, invalid_json or validation_failed
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 409 notice_closed or moderation_conflict
  • 413 payload_too_large
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/admin/dmca/{id}/reject

Reject a DMCA notice

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Update the notice state. Optional JSON body limit: 8 KiB.

Parameters

  • id string path required

Body object

  • note string | null

Responses

  • 200 Success object
  • 400 bad_request, invalid_json or validation_failed
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 409 notice_closed or moderation_conflict
  • 413 payload_too_large
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/admin/dmca/counter-notices/{id}/forward

Forward a counter notice

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Update the counter notice state.

Parameters

  • id string path required

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 409 conflict, notice_closed, restore_not_due or moderation_conflict
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/admin/dmca/counter-notices/{id}/restore

Restore a counter notice

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Restore content after the forwarded counter notice’s restore deadline.

Parameters

  • id string path required

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 409 conflict, notice_closed, restore_not_due or moderation_conflict
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/admin/dmca/counter-notices/{id}/reject

Reject a counter notice

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Update the counter notice state.

Parameters

  • id string path required

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 409 conflict, notice_closed, restore_not_due or moderation_conflict
  • 500 internal_error
  • 503 service_unavailable
GET /api/v1/admin/outbox

Read synchronization and purge status

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Return pending synchronization, failed users and purge backlogs.

Responses

  • 200 Success object
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 500 internal_error
  • 503 service_unavailable
POST /api/v1/admin/outbox/{userId}/retry

Retry a user synchronization

  • Session

Requires a session and administrator membership. Suspended administrators cannot write. Reset pending outbox attempts for a user and schedule processing. Any request body is ignored but bounded to 8 KiB.

Parameters

  • userId string path required

Responses

  • 204 Completed; no response body.
  • 401 unauthorized or invalid bearer token
  • 403 forbidden, csrf_origin, account_suspended or embed_restricted
  • 404 not_found
  • 413 payload_too_large
  • 500 internal_error
  • 503 service_unavailable

Meta

API metadata and documentation.

GET /api/v1/openapi.json

Read the OpenAPI document

  • None

Return the generated OpenAPI 3.1 specification for the implemented public API v1.

Responses

  • 200 Success object
  • 500 internal_error
  • 503 service_unavailable

Schemas

The objects the endpoints send and receive. Names match the TypeScript types in @tiero/spec.

CatalogDTO 19 fields
  • id string required
  • owner object required
  • slug string required
  • title string required
  • description string required
  • game string | null required
  • tags string[] required
  • visibility 'public' | 'unlisted' | 'private' required
  • showNames boolean required
  • version number required
  • rev number required
  • itemCount number required
  • groups object[]
  • defaultTiers object[]
  • license object | null required
  • branding object | null required
  • items CatalogItemDTO[] required
  • itemsPaged boolean required
  • updatedAt string required
CatalogItemDTO 11 fields
  • id string required
  • name string required
  • imageUrl string | null required
  • width number | null required
  • height number | null required
  • group string | null required
  • color string | null required
  • sourceUrl string | null required
  • credit object | null required
  • attributes object required
  • status 'active' | 'removed' | 'unavailable' required
CatalogPutResultDTO 9 fields
  • slug string required
  • owner string required
  • version number required
  • rev number required
  • changed boolean required
  • itemCount number required
  • removedCount number required
  • url string required
  • warnings string[] required
CatalogSummaryDTO 12 fields
  • id string required
  • owner object required
  • slug string required
  • title string required
  • description string required
  • game string | null required
  • tags string[] required
  • version number required
  • rev number required
  • itemCount number required
  • branding object | null required
  • updatedAt string required
ConsensusDTO 4 fields
  • catalog object required
  • listCount number required
  • computedAt string required
  • tiers object[] required
ErrorDTO 1 field
  • error object required
ListDTO 12 fields
  • id string required
  • title string required
  • description string required
  • owner object required
  • catalog object required
  • tiers object[] required
  • visibility 'public' | 'unlisted' | 'private' required
  • likeCount number required
  • createdAt string required
  • updatedAt string required
  • revision number required
  • url string required
ListSummaryDTO 12 fields
  • id string required
  • title string required
  • owner object required
  • catalog object required
  • visibility 'public' | 'unlisted' | 'private' required
  • likeCount number required
  • tierCount number required
  • cardCount number required
  • previewItems CatalogItemDTO[] required
  • createdAt string required
  • updatedAt string required
  • url string required
ListViewerDTO 3 fields
  • likedByViewer boolean required
  • isOwner boolean required
MediaDTO 8 fields
  • id string required
  • url string | null required
  • width number | null required
  • height number | null required
  • bytes number | null required
  • mime string required
  • status 'active' | 'unavailable' required
  • createdAt string | null required
ProviderDomainDTO 8 fields
  • id string required
  • domain string required
  • verified boolean required
  • verifiedAt string | null required
  • lastCheckedAt string | null required
  • createdAt string required
  • txt object required
  • wellKnown object required
CatalogPatch 4 fields
  • title string
  • description string
  • tags string[]
  • visibility 'public' | 'unlisted' | 'private'
CatalogPut 13 fields
  • spec 'tiero-catalog/1' required
  • slug string required
  • title string required
  • description string
  • game string
  • tags string[]
  • visibility 'public' | 'unlisted' | 'private'
  • showNames boolean
  • license object
  • defaultTiers object[]
  • groups object[]
  • branding object
  • items object[] required
DomainCreate 1 field
  • domain string required
EmbedConfig 6 fields
  • name string required
  • mode 'builder' | 'board'
  • allowedOrigins string[] required
  • catalogs array | null
  • theme object
  • listUrlTemplate string | null
EmbedToken 3 fields
  • embedId string required
  • verifier string required
  • code string required
ItemsResolve 1 field
  • ids string[] required
KeyCreate 3 fields
  • name string required
  • scopes 'catalogs:write' | 'media:write' | 'lists:read' | 'lists:write'[] required
  • expiresInDays 30 | 90 | 365 | null
ListCopy 3 fields
  • title string
  • description string
  • visibility 'public' | 'unlisted' | 'private'
ListCreate 7 fields
  • catalog string required
  • title string required
  • description string
  • visibility 'public' | 'unlisted' | 'private'
  • schemaVersion 1 required
  • board object required
  • pool string[]
ListUpdate 7 fields
  • catalog string
  • title string required
  • description string
  • visibility 'public' | 'unlisted' | 'private'
  • schemaVersion 1 required
  • board object required
  • pool string[]
Report 4 fields
  • targetType 'catalog' | 'item' | 'media' | 'list' | 'user' required
  • targetId string required
  • reason 'spam' | 'sexual' | 'hate' | 'harassment' | 'violence' | 'copyright' | 'impersonation' | 'other' required
  • note string | null
ApiKeyDTO 7 fields
  • id string required
  • name string required
  • prefix string required
  • scopes string[] required
  • createdAt string required
  • lastUsedAt string | null required
  • expiresAt string | null required
OAuthGrantDTO 6 fields
  • id string required
  • clientId string required
  • clientName string required
  • scopes string[] required
  • createdAt string required
  • expiresAt string | null required
DmcaNotice 11 fields
  • complainantName string required
  • complainantOrg string | null
  • complainantEmail string required
  • complainantAddress string required
  • complainantPhone string required
  • workDescription string required
  • urls string | string[] required

    One to fifty URLs, as an array or newline-separated string.

  • goodFaith true required
  • accuracyPerjury true required
  • signature string required
  • turnstileToken string required

    Required valid Turnstile verification token.

DmcaCounterNotice 8 fields
  • fullName string required
  • address string required
  • phone string required
  • statement string required
  • mistakePerjury true required
  • consentJurisdiction true required
  • signature string required
  • turnstileToken string required

    Required valid Turnstile verification token.

EmbedDTO 11 fields
  • id string required
  • name string required
  • mode 'builder' | 'board' required
  • allowedOrigins string[] required
  • catalogs array | null required
  • theme object required
  • listUrlTemplate string | null required
  • createdAt string required
  • updatedAt string required
  • disabledAt string | null required
  • snippets object required
ConnectedSite 7 fields
  • id string required
  • embedId string required
  • embedName string | null required
  • origin string required
  • createdAt string required
  • lastSeenAt string required
  • expiresAt string required