Skip to main content
Self-hosted image infrastructure

Image infrastructure for paths your app already knows.

Store, transform, and deliver images at URLs like /assets/users/123/profile-picture—without persisting opaque media IDs in your application.

# Store an image where your app already knows it belongs
POST /assets/users/123/profile-picture

# Read the current image from the same stable path
GET /assets/users/123/profile-picture/-/content

# Request a reusable transformed variant
GET /assets/users/123/profile-picture/-/content?profile=thumbnail
Replace the image later. Your application keeps the same URL.
Why Konifer

One image lifecycle, shaped around your application

Konifer brings storage, transformation, replacement, and delivery behind an API that follows the domain model your product already has.

Application-shaped asset paths

Use URLs that match your product model, such as users, organizations, listings, posts, and documents. Konifer does not force your app to persist opaque media IDs just to render an asset later.

One API for storage and delivery

Store originals, attach metadata, request the newest asset at a path, address a specific entry, or fetch generated variants through the same HTTP surface.

Infrastructure under your control

Choose where Konifer runs, where originals and variants are stored, and how content reaches clients through direct responses, object-store links, redirects, or a CDN.

Stable paths

Replace an image without changing its URL

Post a new asset to the same path and the default request resolves to the newest entry. Your app can replace an avatar or publish a new hero image without updating the URL it already knows.

Select a specific entry when you need history, then choose whether Konifer returns content, a link, a redirect, a download, or structured information.

Explore asset selection
Stable application path/assets/products/sku-123/hero
Initial uploadPOST
ReplacementPOST
Default GETnewest asset
Asset selection
/-/newMost recently created/-/modifiedMost recently modified/-/entry/42Absolute asset reference
Response mode
/-/content/-/link/-/redirect/-/download/-/info
Reusable variants

Transform once, reuse the result

Request image variants on demand or define named profiles for common outputs. Generated variants are stored and reused, so expensive work does not repeat for every viewer.

JPEGPNGWebPAVIFJPEG XLHEICGIF
Request/assets/products/sku-123/hero/-/content?profile=social-card
Generated once1200 × 630 WebPStored and reused on later requests
Policy by path

Configure behavior where images belong

Configure behavior by path pattern, then let inheritance do the work. Public avatars, private user content, CMS images, and generated media can share one service while using different storage buckets, upload rulesets, eager variants, preprocessing, redirect strategies, caching, and LQIP behavior.

Read Path Configuration
paths {
  "/public/avatars/**" {
    transform { eager-variants = [ small, medium, large ] }
    return-format.redirect.strategy = template
    cache-control.max-age = 31536000
  }
  "/users/*/profile-picture" {
    bucket = "profile-pictures"
    allowed-content-types = [ "image/jpeg" ]
  }
}
Content-aware upload rules

Reject the wrong image before it becomes an asset

Evaluate uploads with zero-shot image classification before they are stored. Define reusable rules, attach them to path patterns, and give each area of your product its own visual content policy.

Explore Upload Rules
rule-definitions {
  "product-photo" {
    prompts = [
      "a clean catalog image of a product",
      "a product photo on a plain background"
    ]
    threshold = 0.66
  }
}

paths {
  "/catalog/products/**" {
    upload-ruleset {
      default = reject
      accept-rules = [ { rule = "product-photo" } ]
    }
  }
}
Try Konifer

Run your first image workflow locally

Start Konifer, upload an image to an application-shaped path, and request a cached variant in a few steps.