curl --request POST \
--url https://api.samsa.ai/public/v1/images/upscales \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"image": {
"image_id": "123e4567-e89b-12d3-a456-426614174000"
},
"model": "crystal",
"target_resolution": "4K"
}
'import requests
url = "https://api.samsa.ai/public/v1/images/upscales"
payload = {
"image": { "image_id": "123e4567-e89b-12d3-a456-426614174000" },
"model": "crystal",
"target_resolution": "4K"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
image: {image_id: '123e4567-e89b-12d3-a456-426614174000'},
model: 'crystal',
target_resolution: '4K'
})
};
fetch('https://api.samsa.ai/public/v1/images/upscales', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.samsa.ai/public/v1/images/upscales",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'image' => [
'image_id' => '123e4567-e89b-12d3-a456-426614174000'
],
'model' => 'crystal',
'target_resolution' => '4K'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.samsa.ai/public/v1/images/upscales"
payload := strings.NewReader("{\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n },\n \"model\": \"crystal\",\n \"target_resolution\": \"4K\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.samsa.ai/public/v1/images/upscales")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n },\n \"model\": \"crystal\",\n \"target_resolution\": \"4K\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.samsa.ai/public/v1/images/upscales")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n },\n \"model\": \"crystal\",\n \"target_resolution\": \"4K\"\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "pending",
"estimated_credits": 5
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}Ein Bild hochskalieren
Reiche einen Upscale-Job ein — ein Quellbild auf eine höhere Zielauflösung — und erhalte eine Job-id zurück.
curl --request POST \
--url https://api.samsa.ai/public/v1/images/upscales \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"image": {
"image_id": "123e4567-e89b-12d3-a456-426614174000"
},
"model": "crystal",
"target_resolution": "4K"
}
'import requests
url = "https://api.samsa.ai/public/v1/images/upscales"
payload = {
"image": { "image_id": "123e4567-e89b-12d3-a456-426614174000" },
"model": "crystal",
"target_resolution": "4K"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
image: {image_id: '123e4567-e89b-12d3-a456-426614174000'},
model: 'crystal',
target_resolution: '4K'
})
};
fetch('https://api.samsa.ai/public/v1/images/upscales', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.samsa.ai/public/v1/images/upscales",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'image' => [
'image_id' => '123e4567-e89b-12d3-a456-426614174000'
],
'model' => 'crystal',
'target_resolution' => '4K'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.samsa.ai/public/v1/images/upscales"
payload := strings.NewReader("{\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n },\n \"model\": \"crystal\",\n \"target_resolution\": \"4K\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.samsa.ai/public/v1/images/upscales")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n },\n \"model\": \"crystal\",\n \"target_resolution\": \"4K\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.samsa.ai/public/v1/images/upscales")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n },\n \"model\": \"crystal\",\n \"target_resolution\": \"4K\"\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "pending",
"estimated_credits": 5
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}image mit einem von vier Modellen auf eine höhere
target_resolution. Der Aufruf gibt 202 Accepted mit einer Job-id zurück;
frage GET /images/upscales/{id} nach dem
Ergebnis ab. Das image nimmt genau eines von image_id, url oder
base64 + mime_type. Erfordert den images.transform-Scope.
Beispiel: eine Quelle pro Modus
curl -X POST https://api.samsa.ai/public/v1/images/upscales \
-H "Authorization: Bearer $SAMSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": { "image_id": "123e4567-e89b-12d3-a456-426614174000" },
"model": "crystal",
"target_resolution": "4K"
}'
curl -X POST https://api.samsa.ai/public/v1/images/upscales \
-H "Authorization: Bearer $SAMSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": { "url": "https://cdn.example.com/photo.png" },
"model": "seedvr",
"target_resolution": "2K"
}'
curl -X POST https://api.samsa.ai/public/v1/images/upscales \
-H "Authorization: Bearer $SAMSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": { "base64": "iVBORw0KGgoAAAANSUhEUg...", "mime_type": "image/png" },
"model": "magnific-precision",
"target_resolution": "6K",
"options": { "magnific_precision": { "flavor": "photo", "sharpen": 20, "ultra_detail": 40 } }
}'
Beispiel: magnific-creative mit Optionen
{
"image": { "image_id": "123e4567-e89b-12d3-a456-426614174000" },
"model": "magnific-creative",
"target_resolution": "8K",
"options": {
"magnific_creative": {
"prompt": "sharp studio product photo",
"optimized_for": "films_n_photography",
"creativity": 2,
"hdr": 1,
"engine": "magnific_sharpy"
}
},
"webhook_url": "https://example.com/webhooks/samsa"
}
202-Antwort ist das asynchrone Job-Handle:
{
"id": "d5e6f7a8-9b0c-4d1e-2f3a-4b5c6d7e8f9a",
"status": "pending",
"estimated_credits": 75
}
model ist crystal (Standard), seedvr, magnific-creative oder
magnific-precision. target_resolution ist erforderlich und stammt aus einer
geschlossenen Menge: 2K, 4K, 6K, 8K, 10K, 12K, 14K, 16K, 20K,
24K, 28K, 32K, 38K. Klassen über 16K sind nur für crystal gültig. Die
pro-Modell-Faktor- und Flächenobergrenzen werden vor jeder Abrechnung
validiert — eine Anfrage über der Obergrenze ist ein 422, niemals ein
abgerechneter Job.options sind pro Modell, typisiert und streng validiert: übergib
magnific_creative für das magnific-creative-Modell oder magnific_precision
für magnific-precision. seedvr und crystal nehmen keine Optionen — options
für sie zu übergeben ist ein 422. Unbekannte Keys oder Werte außerhalb des
Bereichs sind 422.magnific_creative:prompt(≤ 500 Zeichen),optimized_for(standard·soft_portraits·hard_portraits·art_n_illustration·videogame_assets·nature_n_landscapes·films_n_photography·3d_renders·science_fiction_n_horror),creativity/hdr/resemblance/fractality(Ganzzahlen −10…10),engine(automatic·magnific_illusio·magnific_sharpy·magnific_sparkle).magnific_precision:sharpen/smart_grain/ultra_detail(Ganzzahlen 0…100),flavor(sublime(Standard) ·photo·photo_denoiser).
Credits
Die Kosten sind die Auflösungsstufe (2K:5, 4K:10, 6K:20, 8K:25, 10K:35,
12K:45, 14K:60, 16K:80) multipliziert mit dem Credit-Multiplikator des Modells
(Magnific ×3); Crystal über 12K rechnet nach Ausgabe-Megapixeln ab. Die
estimated_credits in der 202-Antwort entsprechen exakt dem Abzug. Siehe
Preise.
Fehler
| Status | Code | Wann |
|---|---|---|
402 | insufficient_credits / insufficient_team_credits / insufficient_unallocated_credits | Der Stand, den dieses Credential ausgeben kann, liegt unter den Job-Kosten. Organisationen mit mindestens einem aktiven Team erhalten statt insufficient_credits die team-bezogenen Codes (ausgenommen vom Team-Budgeting befreite System-Organisationen). Ein operativer Fehler in der Abbuchung selbst kann dennoch das generische insufficient_credits liefern, unabhängig vom Regime. |
402 | subscription_inactive | Die Organisation hat kein nutzbares Abonnement. |
403 | missing_scope | Dem Schlüssel fehlt der images.transform-Scope. |
404 | not_found | Die Quell-image_id ist unbekannt oder gehört nicht dem Key-Ersteller — auch ein Bild, das ein anderes Mitglied deiner Organisation erstellt hat, ist ein 404. |
422 | validation_error | Null/mehrere Quellmodi, fehlende/ungültige target_resolution, eine Klasse über der Obergrenze oder ungültige/falsch platzierte options. |
429 | rate_limited / too_many_active_jobs | Pro-Schlüssel-Ratenfenster oder pro-Organisation-Concurrency-Limit überschritten. |
Autorisierungen
Organization API key as a bearer token: Authorization: Bearer samsa_sk_....
Body
POST /images/upscales body (SAM-819 / S8.7 — ADR §7, §8, §10).
Upscale ONE source image to a higher target_resolution with one of the
four public models. The source is exactly one of image_id (an image in
your organization's context), an https url, or base64+mime_type.
target_resolution is a CLOSED set — the per-model factor/area caps are
validated BEFORE charging (an over-cap request is a 422, never a charged
job). options are per-model, typed, and STRICTLY validated (out-of-range /
unknown values are 422 — a documented deviation from the app's clamping).
Cost is the existing upscale estimator: the resolution tier
(2K:5, 4K:10, 6K:20, 8K:25, 10K:35, 12K:45, 14K:60, 16K:80) x the model
credit multiplier (Magnific x3); Crystal above 12K prices by output
megapixels. estimated_credits in the 202 equals the deduction exactly.
The source image: exactly one of image_id, an https url, or base64+mime_type.
Show child attributes
Show child attributes
Target resolution class (REQUIRED) — one of 2K, 4K, 6K, 8K, 10K, 12K, 14K, 16K, 20K, 24K, 28K, 32K, 38K. Classes above 16K are only valid for crystal. The per-model factor/area caps are validated before charging.
2K, 4K, 6K, 8K, 10K, 12K, 14K, 16K, 20K, 24K, 28K, 32K, 38K "4K"
Upscale model: seedvr, crystal (default), magnific-creative, or magnific-precision.
seedvr, crystal, magnific-creative, magnific-precision "crystal"
Per-model tuning options (typed). Only magnific-creative and magnific-precision accept options — supplying options for seedvr/crystal is a 422.
Show child attributes
Show child attributes
Optional https webhook notified once on terminal status (signed per the webhook signature scheme; see the webhooks docs).
"https://example.com/webhooks/samsa"
Antwort
Successful Response
Shared 202 body for the transform-op submits (SAM-813 / S8 wave).
Every POST /images/<op> returns the async job handle
{id, status, estimated_credits}. The initial status is pending (the
job is queued), with ONE exception: background-removals and
vectorizations answer an owned-image_id cache hit (a ready result
already exists for that image) with status: "completed" and
estimated_credits: 0 — no new job is queued, the completed webhook
event is emitted immediately for a supplied webhook_url, and the result
is already available from the op's GET .../{id} endpoint. The other
transform ops (img2img, variations, resizes, upscales) always
start pending.
The job id — poll the op's GET .../{id} endpoint.
Initial status: pending (job queued — enter the polling flow), or completed with estimated_credits: 0 when background-removals / vectorizations serve an owned-image cache hit (the result is immediately available).
pending, processing, completed, failed, cancelled "pending"
Credits this job is expected to cost — 0 on a cache-hit completed response.
5

