Erste Schritte
Vom leeren Konto bis zu Ihrer ersten hochgeladenen Datei – in fünf Schritten.
npm install @uploadcenter/sdk-jsimport { createClient } from "@uploadcenter/sdk-js";
const client = createClient({
baseUrl: "https://api.uploadscenter.com",
token: process.env.UPLOADCENTER_API_KEY, // an API key from your project settings
});Jede Methode wird aus dem OpenAPI-Schema von UploadCenter generiert, sodass die Autovervollständigung die gesamte API-Oberfläche abdeckt — Das JS-Paket auf npm anzeigen oder das Python-Paket auf PyPI.
curl -X POST https://api.uploadscenter.com/v1/uploads/presign \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"project_id": "project_...",
"filename": "photo.jpg",
"size_bytes": 128000,
"mime_type": "image/jpeg",
"visibility": "private"
}'curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: image/jpeg" \
--data-binary @photo.jpgcurl -X POST https://api.uploadscenter.com/v1/uploads/complete \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"file_id": "file_..."}'Eine Datei zurücklesen — GET /v1/files/{file_id}/url — Für private Dateien ist immer ein gültiger API-Schlüssel oder eine gültige Sitzung erforderlich. Bei öffentlichen Dateien gilt eine andere Regelung – siehe unten.
GET /v1/files/{file_id}
{
"id": "file_...",
"visibility": "public",
"status": "ready",
"url": "https://cdn.uploadscenter.com/o/…/photo.jpg"
}Private Dateien (Standardeinstellung) verfügen nicht über ein URL-Feld – rufen Sie stattdessen GET /v1/files/{id}/url auf, wodurch ein neuer, signierter Link zurückgegeben wird, der für einen begrenzten Zeitraum gültig ist.
POST <your webhook URL>
Content-Type: application/json
X-Signature: sha256=<hex-encoded HMAC-SHA256>
X-Timestamp: <unix timestamp, seconds>
{"event":"file.processed","created_at":"2026-01-01T12:00:00Z","data":{"id":"file_...","project_id":"project_...","status":"ready", ...}}Veranstaltungen: file.uploaded, file.processed, file.failed, file.quarantined, file.flagged, storage.limit_reached. Bis zu 3 Zustellversuche (mit einer Wartezeit von 30 Sekunden, 2 Minuten bzw. 10 Minuten) sind zulässig, bevor eine Zustellung als fehlgeschlagen markiert wird.
import crypto from "node:crypto";
// Sign over "${timestamp}.${rawBody}" — rawBody must be the exact bytes
// received, not a re-serialized JSON.stringify(JSON.parse(rawBody)).
function verifyWebhook(rawBody: string, timestamp: string, signatureHeader: string, secret: string): boolean {
const expected = crypto.createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");
const provided = signatureHeader.replace(/^sha256=/, "");
return crypto.timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(provided, "hex"));
}
// signatureHeader = req.headers["x-signature"]
// timestamp = req.headers["x-timestamp"]GET /v1/files/{file_id}/transform?w=480&h=320&format=auto&fit=cover
# fit: "cover" (crop to fill) or "inside" (contain)
# format: auto (default) | webp | jpeg | png
# quality: auto (default) | 1-100
#
# format=auto picks WebP or JPEG based on the request's Accept header —
# no more branching client-side for older browsers. quality=auto applies
# a sensible per-format default (80 for WebP, 82 for JPEG). Pass explicit
# values any time you want full control instead.PUT /v1/projects/{project_id}/watermark
{"file_id": "file_..."} # any image already uploaded to the project
GET /v1/files/{file_id}/transform?w=1200&watermark=true&gravity=south_east&opacity=60&overlay_scale=0.2
# gravity: north_west | north_east | south_west | south_east | center
# opacity: 1-100 (default 60)
# overlay_scale: 0.05-1.0 (default 0.2, fraction of the output image's width)POST /v1/domains
{"project_id": "project_...", "hostname": "cdn.yourapp.com"}
# Add the returned TXT record at your DNS provider, then:
POST /v1/domains/{domain_id}/verify
# Once verified, point cdn.yourapp.com at UploadCenter (A/CNAME — shown in
# the dashboard) and a TLS certificate is issued automatically. From then
# on, every public file's url uses your domain instead of the shared CDN.GET /v1/files/{file_id}
{
"id": "file_...",
"status": "ready",
"moderation_status": "flagged", // null (not evaluated) | "clean" | "flagged" | "error"
"moderation_score": 0.87
}Eine als „markiert“ gekennzeichnete Datei bleibt genau so, wie sie hochgeladen wurde – Ihre App legt fest, was „markiert“ für Ihr Produkt bedeutet. Verfügbar in kostenpflichtigen Tarifen; siehe die Seite mit den Funktionen.
GET /v1/files/{file_id}/variants
[
{ "variant": "thumbnail", "format": "jpg", "width": 640, "height": 360, "url": "https://…" },
{ "variant": "720p", "format": "mp4", "width": 1280, "height": 720, "url": "https://…" }
]const generation = await client.ai.generateImageEndpointV1AiImagesGeneratePost({
project_id: projectId,
prompt: "a minimalist logo of a fox, flat vector style",
use_brand_kit: true, // pulls in this org's brand kit colors/fonts
});
// 202 Accepted — poll until it settles (or listen for the webhook below).
const result = await client.ai.getGenerationEndpointV1AiGenerationsGenerationIdGet(
generation.id,
projectId,
);
// result.file_ids — the new file(s), same shape as anything you uploadDas Ergebnis ist eine gewöhnliche Datei – „file_ids“ nach Abschluss der Generierung – mit eigener Sichtbarkeit, Zustellung und eigenem Lebenszyklus, genau wie alles, was Sie direkt hochladen.
GET /v1/ai/search?project_id={project_id}&q=cat+sitting+on+a+couch&limit=20
# Ranks files by AI caption similarity (files.ai_caption, produced by the
# analyze-image capability) — not full-text search over filenames.
# GET /v1/files/{file_id}/similar finds files with a similar caption.Möchten Sie den vollständigen Überblick?
Auf der Seite „Funktionen“ finden Sie alle Funktionen – Versionsverwaltung, benutzerdefinierte Domains, Teamrollen und vieles mehr.