curl --request POST \
--url https://api.samsa.ai/public/v1/images/resizes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"aspect_ratio": "16:9",
"image": {
"image_id": "123e4567-e89b-12d3-a456-426614174000"
}
}
'import requests
url = "https://api.samsa.ai/public/v1/images/resizes"
payload = {
"aspect_ratio": "16:9",
"image": { "image_id": "123e4567-e89b-12d3-a456-426614174000" }
}
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({
aspect_ratio: '16:9',
image: {image_id: '123e4567-e89b-12d3-a456-426614174000'}
})
};
fetch('https://api.samsa.ai/public/v1/images/resizes', 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/resizes",
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([
'aspect_ratio' => '16:9',
'image' => [
'image_id' => '123e4567-e89b-12d3-a456-426614174000'
]
]),
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/resizes"
payload := strings.NewReader("{\n \"aspect_ratio\": \"16:9\",\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n }\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/resizes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"aspect_ratio\": \"16:9\",\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.samsa.ai/public/v1/images/resizes")
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 \"aspect_ratio\": \"16:9\",\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n }\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"
}
}Redimensionner une image
Soumets un job de redimensionnement — une image source vers un nouveau ratio (outpainting côté serveur).
curl --request POST \
--url https://api.samsa.ai/public/v1/images/resizes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"aspect_ratio": "16:9",
"image": {
"image_id": "123e4567-e89b-12d3-a456-426614174000"
}
}
'import requests
url = "https://api.samsa.ai/public/v1/images/resizes"
payload = {
"aspect_ratio": "16:9",
"image": { "image_id": "123e4567-e89b-12d3-a456-426614174000" }
}
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({
aspect_ratio: '16:9',
image: {image_id: '123e4567-e89b-12d3-a456-426614174000'}
})
};
fetch('https://api.samsa.ai/public/v1/images/resizes', 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/resizes",
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([
'aspect_ratio' => '16:9',
'image' => [
'image_id' => '123e4567-e89b-12d3-a456-426614174000'
]
]),
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/resizes"
payload := strings.NewReader("{\n \"aspect_ratio\": \"16:9\",\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n }\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/resizes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"aspect_ratio\": \"16:9\",\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.samsa.ai/public/v1/images/resizes")
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 \"aspect_ratio\": \"16:9\",\n \"image\": {\n \"image_id\": \"123e4567-e89b-12d3-a456-426614174000\"\n }\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 source vers un nouveau aspect_ratio. Le redimensionnement
est un outpainting côté serveur : le backend rend la composition et le masque à
partir de ta source au ratio cible et remplit la nouvelle toile exposée avec une
extension assortie au style. L’appel renvoie 202 Accepted avec un id de job ;
interroge GET /images/resizes/{id} pour le
résultat. L’image prend exactement un de image_id, url ou
base64 + mime_type. Requiert le scope images.transform.
Exemple : une source par mode
curl -X POST https://api.samsa.ai/public/v1/images/resizes \
-H "Authorization: Bearer $SAMSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": { "image_id": "123e4567-e89b-12d3-a456-426614174000" },
"aspect_ratio": "16:9"
}'
curl -X POST https://api.samsa.ai/public/v1/images/resizes \
-H "Authorization: Bearer $SAMSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": { "url": "https://cdn.example.com/portrait.png" },
"aspect_ratio": "1:1",
"resolution": "2K",
"placement": { "gravity": "top", "scale": 0.8 }
}'
curl -X POST https://api.samsa.ai/public/v1/images/resizes \
-H "Authorization: Bearer $SAMSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": { "base64": "iVBORw0KGgoAAAANSUhEUg...", "mime_type": "image/png" },
"aspect_ratio": "21:9",
"num_outputs": 2,
"prompt": "extend the mountain range on both sides",
"webhook_url": "https://example.com/webhooks/samsa"
}'
202 est le handle de job asynchrone :
{
"id": "e6f7a8b9-0c1d-4e2f-3a4b-5c6d7e8f9a0b",
"status": "pending",
"estimated_credits": 5
}
aspect_ratio est requis et l’un de 21:9, 16:9, 3:2, 4:3, 5:4, 1:1,
4:5, 3:4, 2:3, 9:16. resolution (1K défaut, 2K, 4K) est une
métadonnée fournisseur qui met à l’échelle les credits — la toile est toujours
rendue avec un bord maximal de 1024px. num_outputs (1 à 4) vaut 1 par défaut
et chaque sortie (output) est facturée. prompt est une instruction facultative
pour la zone nouvellement générée (validée si non vide). placement positionne la
source sur la toile cible : gravity est l’un de center (défaut), top,
bottom, left, right, top_left, top_right, bottom_left, bottom_right ;
scale est dans (0, 1] (défaut 1.0 = contain-fit maximal).aspect_ratio + placement demandés ne laissent
(presque) aucune nouvelle zone à générer — p. ex. la source correspond déjà au
ratio cible à scale = 1 — et qu’aucun prompt n’est fourni, le job saute le
modèle, renvoie la composition aplatie et rembourse les sorties inutilisées. Il
completes tout de même.Credits
Chaque sortie (output) coûte5 credits en 1K, en fonction de la résolution
(1K ×1, 2K ×2, 4K ×4) et multiplié par num_outputs. Voir
Tarifs.
Erreurs
| Statut | Code | Quand |
|---|---|---|
402 | insufficient_credits / insufficient_team_credits / insufficient_unallocated_credits | Le solde que ce credential peut dépenser est en dessous du coût du job. Les organisations avec au moins une équipe active reçoivent les codes liés aux équipes à la place de insufficient_credits (sauf les organisations système exemptées du budgeting par équipe). Une défaillance opérationnelle dans la déduction elle-même peut néanmoins renvoyer le générique insufficient_credits, quel que soit le régime. |
402 | subscription_inactive | L’organisation n’a aucun abonnement utilisable. |
403 | missing_scope | La clé n’a pas le scope images.transform. |
404 | not_found | L’image_id source est inconnu ou n’appartient pas au créateur de la clé — une image créée par un autre membre de ton organisation renvoie aussi un 404. |
422 | validation_error | Zéro/plusieurs modes source, aspect_ratio manquant/invalide, placement invalide, un prompt contraire à la politique, ou une image raster source au-dessus de 33 554 432 pixels (32 MP, largeur × hauteur), rejetée avec param: image avant tout rendu. |
429 | rate_limited / too_many_active_jobs | Fenêtre de débit par clé ou plafond de concurrence par organisation dépassé. |
Autorisations
Organization API key as a bearer token: Authorization: Bearer samsa_sk_....
Corps
POST /images/resizes body (SAM-818 / S8.6 — ADR §8, §10).
Resize = server-side outpaint: the backend renders the composition + mask from
your source at the target aspect_ratio and fills the newly exposed canvas
with a style-matched extension. The source is exactly one of image_id (an
image in your organization's context), an https url, or base64+mime_type.
aspect_ratio is REQUIRED (validated against the resize engine's supported
list). num_outputs defaults to 1; each output is billed at
5 x resolution_multiplier credits (1K:1x, 2K:2x, 4K:4x).
Empty-mask no-op: when the requested aspect_ratio + placement leave (almost)
no new area to generate (e.g. the source already matches the target ratio at
scale=1) and no prompt is given, the job SKIPS the model, returns the
flattened composition, and REFUNDS the unused outputs — it still completes.
The source image: exactly one of image_id, an https url, or base64+mime_type. The source raster must be at most 33,554,432 pixels (32 MP, width x height) — a larger source returns 422 with param: image before any rendering. The composition canvas is at most 1024px per edge, so higher-resolution sources gain no output detail.
Show child attributes
Show child attributes
Target aspect ratio (REQUIRED) — one of: 21:9, 16:9, 3:2, 4:3, 5:4, 1:1, 4:5, 3:4, 2:3, 9:16.
"16:9"
Provider resolution tier — 1K (default), 2K, or 4K. The canvas is always rendered at a 1024px max edge (per S8.5); the tier is provider metadata that scales credits 1K:1x, 2K:2x, 4K:4x per output.
"1K"
Number of images to generate (1-4). Defaults to 1; each output is billed.
1 <= x <= 41
Optional instruction for the newly generated area. When non-empty it runs the app's prompt validation (rejects empty / malformed / policy-violating prompts with a 422).
"extend the beach and the ocean horizon naturally"
Optional placement of the source on the target canvas (gravity + scale). Defaults to centered, maximum contain-fit.
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"
Réponse
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

