Pricing

Docs

Docs

Quick Start

Core Concepts

Beginner

How Partikl generates, tracks, and auto-regenerates thumb/index/original for every uploaded file.

Updated Apr 8, 2026

7 min read

4 API refs

Variants

When you upload a file to Partikl, the system runs it through your namespace's active pipeline graph and produces one or more variants — optimized, transformed copies of the original file.

Every namespace has up to three variant kinds per content type:

KindPurposeTypical output
thumbThumbnails, previews, low-res.webp 400×400, ≤ 20 KB
indexDelivery-optimized main version.avif 1920px, ≤ 200 KB
originalArchived source, optionally encryptedoriginal format, full size

Not all kinds are required

Your pipeline defines which variant kinds exist. A namespace with only a resize node produces thumb and index. Adding the original passthrough node creates the third variant.

How variants are created

1

Upload triggers pipeline

When a file upload completes, the namespace's active workflow is resolved. Each active pipeline produces one variant kind.

2

Pipeline hash is snapshot

The current pipeline_hash (FNV-1a 64-bit of the pipeline's semantic JSON) is stored on the variant at creation time. This snapshot is the key to detecting stale variants later.

3

Processing runs asynchronously

The variant transitions through statuses: PROCESSING → READY (or ERROR). You can poll or subscribe to status changes.

4

Variant is served via CDN

Once READY, the variant URL is available and cached at edge. Format: https://cdn.partikl.io/{namespace}/{photoId}/{kind}.{ext}

Variant statuses

Each variant has one of four statuses at any point in time:


— Pipeline is running. File is being transformed.

— Transformation complete. Variant is available and CDN-cached.

— Pipeline failed. Check the errorCode field for details.

— Pipeline definition changed after this variant was created. Variant still served but stale.

OUTDATED variants are still served

An OUTDATED variant continues to be delivered from CDN while regeneration runs. There is no downtime — the new variant atomically replaces the old one when READY.

Auto-regeneration

This is Partikl's core differentiator. When you modify a pipeline (e.g., change resize dimensions, add an encode node, update encryption), the system:

  1. Recomputes the pipeline's pipeline_hash
  2. Compares it against the pipeline_hash snapshot on every existing variant for that pipeline
  3. Marks all mismatching variants as OUTDATED
  4. Queues regeneration jobs in priority order (newest files first)

You don't write a single line of migration code.

pipeline changes → hash changes → variants marked OUTDATED → background regeneration → READY

Pipeline hash is semantic, not structural

Changing a comment in the pipeline JSON does not change the hash. Only semantically meaningful changes (node params, topology, order) trigger regeneration.

Querying variants

QUERY

variants(photoId: ID!)

Auth required

Fetch all variants for a given photo

Fetch all variants for a photo with their current status

The original variant has url: null when the namespace has encryption enabled. Use the signed URL mutation to get a time-limited access URL.

Real-time status updates

Subscribe to variant status changes instead of polling:

SUBSCRIPTION

variantStatusChanged(photoId: ID!)

Auth required

Real-time variant status updates

subscription WatchVariant($photoId: ID!) {
variantStatusChanged(photoId: $photoId) {
  variantId
  kind
  status
  url
  errorCode
}
}

Waiting for all variants

A common pattern — upload, then wait until all variants are READY:

const { photoId } = await client.upload(file, {
namespace: 'dev1',
});

// Waits until thumb + index + original are all READY
// Timeout: 60s by default
const variants = await client.variants.waitForReady(photoId, {
kinds: ['thumb', 'index'],
timeout: 30_000,
});

console.log(variants.thumb.url);
console.log(variants.index.url);

Manual regeneration

Force regeneration of specific variants without changing the pipeline:

MUTATION

regenerateVariant(variantId: ID!, force: Boolean)

Auth required

Trigger manual re-processing of a variant

mutation RegenerateVariant($variantId: ID!) {
regenerateVariant(variantId: $variantId, force: true) {
  variantId
  status
}
}

Variant fields reference

Variant object

variantId

required

ID

Unique variant identifier. Format: {photoId}_{kind}

photoId

required

ID

Parent photo this variant belongs to.

pipelineId

required

ID

The pipeline that created this variant.

pipelineHash

required

String

FNV-1a 64-bit hash of the pipeline at the time this variant was created. Used to detect OUTDATED variants when pipeline changes.

kind

required

VariantKind

One of: thumb | index | original

status

required

VariantStatus

Current status: PROCESSING | READY | OUTDATED | DELETED

url

String

CDN URL. Null if encrypted original or not yet READY.

mimeType

String

Output MIME type (e.g. image/webp, video/mp4).

sizeBytes

Int

File size in bytes. Available once READY.

width

Int

Output width in pixels. Null for audio/file variants.

height

Int

Output height in pixels. Null for audio/file variants.

errorCode

String

Error code if status is ERROR. See error codes reference.

createdAt

required

DateTime

ISO 8601 timestamp when the variant was created.

updatedAt

required

DateTime

ISO 8601 timestamp of last status change.

  • Processing Lifecycle — full upload-to-ready flow
  • Auto-regeneration — how pipeline changes trigger re-processing
  • Status Codes Reference — all status values and transitions
  • Subscriptions — real-time event streaming

Was this page helpful?

Previous

Introduction

Next

Authentication

All systems operational

99.98% uptime

Status page

© 2026 Partikl. All rights reserved.

Phone Number: +995 599 136 221

Move with ❤️ in Georgia

PrivacyTermsDMCAGDPR

GDPR Compliant

CCPA Ready

Data processed in EU / US regions

End-to-end encryption