Import images
View .mdImport images you are authorized to copy into your collection’s media library. This early-access operation family requires a matching API deployment and SDK. It does not publish content, activate routes, or change a site’s credentials.
Use your coding agent
Section titled “Use your coding agent”With manager OAuth, preview import_collection_images using collection_slug and input containing a fresh UUID requestId and up to 50 unique urls (src and optional alt). Review the normalized plan, then confirm the same input with confirm: true and its exact planDigest. Collection ADMIN or MEMBER may import; scoped collection roles may inspect get_collection_media_import. Guest login is not editor authority.
Poll the returned job ID. Use resume_collection_media_import only to recover unfinished work: preview, review, then confirm. An active worker cannot be resumed concurrently. This workflow uses manager OAuth and does not require issuing a site server key.
Imports run asynchronously and may wait in a queue. A pending job is not evidence that downloading started. Interrupted processing resumes from settled source results; failed jobs wait for an explicit authorized resume. Inspect the returned status rather than assuming an accepted request has finished.
Use your server
Section titled “Use your server”Use a restricted server secret with collection-wide media.import for plan/create/resume and independent media.read for progress. The methods are absent from the browser client.
import { createKismetClient } from '@kismet-tech/sdk/server';import { randomUUID } from 'node:crypto';
const kismet = createKismetClient({ collection: 'example-stays', apiKey: process.env.KISMET_SERVER_KEY!, baseUrl: 'https://api.ksmt.app/v1' });const plan = await kismet.mediaImports.plan({ requestId: randomUUID(), urls: [{ src: 'https://media.example.com/waterfront.jpg', alt: 'Waterfront path' }] });// Show plan.input and warnings to the authorized editor before confirming.const job = await kismet.mediaImports.create({ ...plan.input, planDigest: plan.planDigest, confirm: true });const progress = await kismet.mediaImports.get(job.id);// Poll with backoff; completed can include failed sources.for (const result of progress.results) { if (result.status !== 'failed' && result.image) console.log(result.image.id, result.image.url);}REST uses POST /v1/developer/collections/{collection}/media/imports/plan, POST .../imports, GET .../imports/{id}, and POST .../imports/{id}/resume ({ "confirm": true }). Send the server credential in the Authorization header, never in a URL.
Convert a static SVG before importing
Section titled “Convert a static SVG before importing”The shared importer does not store or serve SVG. For self-contained vector logos
and illustrations, the SDK source/evaluation package includes media-converter,
a separate server-side converter. It accepts bounded static geometry and simple
local CSS/clipping, then emits PNG only. Scripts, external resources, entities,
animation, embedded HTML, unsupported constructs, and cyclic references are
rejected; nothing is silently removed except the supported CSS after applying it.
Build the converter from the supplied SDK package (Docker is required):
docker build -t kismet-media-converter ./node_modules/@kismet-tech/sdk/media-converterRun it on one source file you are authorized to copy. Use an empty private output directory, absolute paths, and the full isolation profile:
docker run --rm --user "$(id -u):$(id -g)" \ --network=none --read-only --cap-drop=ALL --security-opt=no-new-privileges \ --pids-limit=64 --memory=256m --cpus=1 \ --tmpfs /tmp:rw,noexec,nosuid,size=16m \ --mount type=bind,source=/absolute/source.svg,target=/input.svg,readonly \ --mount type=bind,source=/absolute/empty-output,target=/output \ kismet-media-converterNever pass production credentials, extra environment variables, or other private
mounts to this container. The converter checks its runtime limits and refuses
host, root, networked, writable-root, or unbounded execution. It caps source bytes
at 512 KiB, normalized geometry at 2 MiB/4,096 nodes/32 levels, output sides at
2,048 pixels (up to 4× intrinsic size), and
rendering at five seconds inside a 20-second process deadline. It does not
overwrite an existing output.png. Retain its source/PNG SHA-256 receipt privately.
There is no local-file upload or arbitrary SVG-storage operation in this API. Serve the resulting PNG from your approved source host and use its HTTPS URL in the normal reviewed media-import request. Inspect the managed-library result before replacing a content binding. Keep the original source unchanged; if a vector uses unsupported features, obtain a reviewed raster export rather than relaxing validation. Retain the unchanged original, conversion receipt, PNG, import request UUID, returned image ID, and owned URL in a private durable audit record. The receipt links the original SVG checksum to the exact PNG checksum; it is not a server attestation of third-party rights. Keep it after the import job expires—Kismet does not retain the original SVG or a permanent conversion receipt in that job. Converting an image does not publish a page.
Recovery and safety
Section titled “Recovery and safety”- Planning writes nothing and is not a reachability or rights check. Creation requires the exact reviewed digest. Replay the identical request UUID to recover its job; changed input with that UUID is rejected.
- Each source yields
imported,existing, orfailed. Only successful owned image URLs belong in subsequent Article drafts. A completed job is not proof every image imported. Retry failed sources in a separately reviewed new request. - Progress persists in the shared cache for 24 hours, including settled source results. Explicit resume skips those results. It is not a permanent receipt or a guarantee against cache data loss; retain your reviewed source-to-owned-URL mapping privately.
- Four new jobs per collection per continuously refilled hour, at most 50 sources per job. Polling does not consume this job budget. Honor
429and back off. Unavailable persistence refuses creation before image writes. - Only public HTTPS JPEG, PNG, WebP, or GIF sources are accepted. Every DNS lookup and redirect is checked against private networks; credentials are not forwarded. Downloads are bounded to 10 MiB and decoded images to 40 million pixels. SVG, mismatched bytes, broken sources, and unsafe redirects fail independently.
- Source URL query strings can contain private access tokens. Do not put source URLs in public logs, browser state, or chat. The library preserves collection ownership and deduplicates image content; it does not grant rights to copy third-party media.
After reviewing the results, replace the appropriate hero/body URLs in an Article import plan, review the new immutable revision, and publish to staging only as a separate authorized action. Production publication is not part of this workflow.