---
title: "Create catalog snapshot diff."
method: POST
path: "/v1/catalog/snapshots/{snapshot_id}/diffs"
tags: ["Catalog"]
---

# Create catalog snapshot diff.

`POST /v1/catalog/snapshots/{snapshot_id}/diffs`

## Request

- Base URL: `https://api.tlmtr.io`
- URL: `https://api.tlmtr.io/v1/catalog/snapshots/{snapshot_id}/diffs`
- Auth: API key in header `x-api-key`
- TypeScript: <https://skmtc.dev/tlmtr/apis/telemetr-io-public-api/docs/v1/catalog/snapshots/:snapshot_id/diffs/post.ts> (a function with typed inputs; its response is checked against the schema)

Apply the snapshot's saved filters to the current catalog and store channels
added or removed relative to the original snapshot, not the previous diff.
The original snapshot is not updated. Returns counts; use List diff changes
with `change_type=added` or `removed` to retrieve channel IDs.
Removed means no longer matching the saved result, not necessarily deleted from Telegram.

The saved baseline and current matching set must both fit the maximum from
your current API plan or Subscription key settings. Larger sets return 422
without truncation. Each diff expires 30 days after its creation.
Your active diff cap applies across all snapshots and is returned as `active_limit`
by List diffs. Reaching it returns 429 `DIFF_LIMIT_REACHED`.
Only one diff creation per user can run at a time; concurrent requests return
429 `DIFF_CREATION_IN_PROGRESS`. Snapshot mutation conflicts also return 429.
Retry temporary conflicts after `Retry-After`. The source snapshot must be active.
Catalog and snapshot access must both be enabled.
Credits keys: 0.400 credits per successful creation, including a diff with
no changes. No additional base or per-channel fee; 30-day storage is included.
Each POST creates and bills a new diff. After a timeout, inspect existing
diffs before retrying: creation requests are not deduplicated.

## Path parameters

- `snapshot_id` string, required

## Response `201`

- CatalogSnapshotDiffResponse
  - `diff_id` string, required: Unique diff identifier. Pass it unchanged to diff endpoints.
  - `snapshot_id` string, required: Unique identifier of the original snapshot. Pass it unchanged to snapshot endpoints.
  - `added_count` integer, required: Channels matching at diff creation that were absent from the original snapshot.
  - `removed_count` integer, required: Channels in the original snapshot that no longer matched at diff creation. This does not necessarily mean deletion from Telegram.
  - `created_at` string, required: Creation timestamp in UTC, formatted as RFC 3339.
  - `expires_at` string, required: Expiration timestamp in UTC, formatted as RFC 3339. Resources expire 30 days after their own creation.

## Other responses

- `402`: Insufficient credits
- `403`: Catalog and snapshot access must both be enabled.
- `404`: Resource not found or not owned by your user.
- `410`: Resource has expired.
- `422`: The saved baseline or current matching set exceeds max_channels returned in the error. Narrow the saved filters.
- `429`: Active resource limit reached or a conflicting operation is in progress. Inspect code; honor Retry-After for temporary conflicts.
- `503`: Snapshot storage is temporarily unavailable.

## Changes

- **2026-10-09** `6c2bfd66c5f2`: 4 breaking, 1 info
  - the response's body type changed from `object` to no type for status `402`
  - removed the required property `available_mc` from the response with the `402` status
  - removed the required property `shortfall_mc` from the response with the `402` status
  - removed the required property `total_cost_mc` from the response with the `402` status
  - …1 more
- **2026-09-10** `80951ad7b3fb`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/tlmtr/apis/telemetr-io-public-api/changes/v1/catalog/snapshots/:snapshot_id/diffs/post.md)

---

[API](https://skmtc.dev/tlmtr/apis/telemetr-io-public-api.md) - [All operations](https://skmtc.dev/tlmtr/apis/telemetr-io-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/tlmtr/apis/telemetr-io-public-api/revisions/98f399867856?raw)
