Skip to main content

Image API

  • Base URL: https://api.samsar.one/v1
  • Auth: Authorization: Bearer <API_KEY>
  • Responses include x-credits-charged and x-credits-remaining when credits are deducted.
  • All endpoints enqueue work; poll /image/status?request_id=... (or /v1/status) for completion, or use /image/list to fetch history.

Pricing

EndpointCreditsNotes
POST /image/enhance45 (1k) / 75 (2k) / 90 (4k)Based on resolution (defaults to 1k).
POST /image/remove_branding75White label images and remove branding for marketplace listing.
POST /image/add_image_set75 × requested_imagesrequested_images = num_images (if provided) else image_urls.length.
POST /image/receipt_templates/createFreeBuilds and saves a receipt template + normalized schema from one sample image.
GET /image/template_jsonFreeReturns the saved structured template JSON for a template_id owned by your API key.
POST /image/receipt_templates/query50Validates receipt against template and returns standardized JSON fields.
POST /image/create_rollup_banner30Flat per request.
POST /image/create_rollup_banner_with_enhanceVariableEnhance credits for low-res images + 30 credits per rollup request.

POST /image/enhance

Upscale and denoise an image.

Request body

{
"image_url": "https://cdn.example.com/photo.png",
"resolution": "1k | 2k | 4k"
}
  • image_url required, non-empty URL.
  • resolution optional; defaults to 1k.

Success response (200)

{
"status": "queued",
"request_id": "img_enh_123",
"session_id": "img_enh_123",
"global_status_id": "img_enh_123",
"case_type": "image_enhance",
"image_url": "https://cdn.example.com/photo.png",
"resolution": "1K",
"aspect_ratio": "16:9",
"creditsCharged": 45,
"remainingCredits": 4955
}

POST /image/remove_branding

Remove a watermark or logo.

Request body

{
"image_url": "https://cdn.example.com/watermarked.png"
}

Success response (200)

{
"status": "queued",
"request_id": "img_rm_123",
"session_id": "img_rm_123",
"global_status_id": "img_rm_123",
"case_type": "logo_remove",
"image_url": "https://cdn.example.com/watermarked.png",
"creditsCharged": 75,
"remainingCredits": 4925
}

POST /image/add_image_set

Extend or save a set of images for downstream generation.

Request body

{
"image_urls": [
"https://cdn.example.com/look1.png",
"https://cdn.example.com/look2.png"
],
"metadata": { "campaign": "spring" },
"prompt": "Optional creative direction",
"num_images": 4
}
  • image_urls required, non-empty array of strings.
  • num_images optional positive number; defaults to image_urls.length when omitted.
  • prompt optional string; metadata optional object.

Success response (200)

{
"status": "queued",
"request_id": "img_set_123",
"session_id": "img_set_123",
"global_status_id": "img_set_123",
"case_type": "image_list_to_image_set",
"image_urls": [
"https://cdn.example.com/look1.png",
"https://cdn.example.com/look2.png"
],
"metadata": { "campaign": "spring" },
"prompt": "Optional creative direction",
"num_images": 4,
"creditsCharged": 300,
"remainingCredits": 4700
}

POST /image/receipt_templates/create

Create and persist a reusable receipt extraction template from a sample receipt image.

This endpoint is free (no credits deducted).

Request body

{
"image_url": "https://cdn.example.com/receipt-template.png",
"template_name": "kbank-transfer-template"
}
  • image_url required, public image URL.
  • template_name optional.

Success response (200)

{
"template_id": "receipt_tpl_0e4f9f1dca744ec9b3a3f8df",
"template_hash": "f8b8f4e6e7d9b66d3f4a9e6f35b17c4d7ac4dce2f0d63f15e2d55b9872e3be35",
"template_name": "kbank-transfer-template",
"normalized_template": {
"schema_version": "1.0",
"merchant_hint": "Kasikornbank",
"currency_hint": "THB",
"rois": [
{ "id": "meta_header", "label": "Header and Meta", "left": 0, "top": 0, "width": 1, "height": 0.35 },
{ "id": "line_items", "label": "Line Items/Table", "left": 0, "top": 0.28, "width": 1, "height": 0.5 },
{ "id": "totals", "label": "Totals", "left": 0.45, "top": 0.7, "width": 0.55, "height": 0.3 }
],
"fields": [
{ "key": "merchant_name", "type": "string", "required": true },
{ "key": "transaction_date", "type": "date", "required": true },
{ "key": "total", "type": "currency", "required": true }
],
"validation_rules": {
"arithmetic": true,
"amount_tolerance": 0.05
}
},
"sample_receipt": {
"merchant_name": "Kasikornbank",
"transaction_date": "2026-01-14",
"total": 786
}
}

POST /image/receipt_templates/query

Extract receipt fields by validating an input receipt image against an existing template.

This endpoint charges 50 credits per request.

Request body

{
"template_id": "receipt_tpl_0e4f9f1dca744ec9b3a3f8df",
"image_url": "https://cdn.example.com/receipt-instance.png"
}
  • template_id required.
  • image_url required.
  • The template must belong to the same API key. Cross-account template access returns 404.

Success response (200)

{
"template_id": "receipt_tpl_0e4f9f1dca744ec9b3a3f8df",
"template_hash": "f8b8f4e6e7d9b66d3f4a9e6f35b17c4d7ac4dce2f0d63f15e2d55b9872e3be35",
"template_name": "kbank-transfer-template",
"receipt_json": {
"merchant_name": "Kasikornbank",
"transaction_date": "2026-01-14",
"transaction_id": "TRBS260114764844309",
"currency": "THB",
"fee": 0,
"total": 786
},
"standardized_receipt": {
"merchant_name": "Kasikornbank",
"transaction_date": "2026-01-14",
"transaction_time": "17:25",
"transaction_id": "TRBS260114764844309",
"currency": "THB",
"subtotal": 786,
"tax": null,
"fee": 0,
"discount": null,
"total": 786,
"payment_method": "transfer",
"from_account": "xxx-x-xxxx-x",
"to_account": "xxx-x-xxxx-x"
},
"items": [],
"unreadable_fields": [],
"confidence": 0.93,
"validation": {
"is_valid": true,
"issues": []
},
"attempts": 1
}

Response headers include:

  • x-credits-charged: 50
  • x-credits-remaining: <remaining>

GET /image/template_json

Fetch a saved structured receipt template by template_id.

This endpoint validates ownership against your API key and returns the template JSON only when the template belongs to that user.

Primary route: GET /image/template_json
Alias route: GET /image/receipt_templates/template_json

Query params

  • template_id required.

Sample request

curl "https://api.samsar.one/v1/image/template_json?template_id=receipt_tpl_0e4f9f1dca744ec9b3a3f8df" \
-H "Authorization: Bearer $SAMSAR_API_KEY"

Success response (200)

{
"template_id": "receipt_tpl_0e4f9f1dca744ec9b3a3f8df",
"template_hash": "f8b8f4e6e7d9b66d3f4a9e6f35b17c4d7ac4dce2f0d63f15e2d55b9872e3be35",
"template_name": "kbank-transfer-template",
"source_image_url": "https://cdn.example.com/receipt-template.png",
"normalized_template": {
"schema_version": "1.0",
"merchant_hint": "Kasikornbank",
"currency_hint": "THB",
"rois": [
{ "id": "meta_header", "label": "Header and Meta", "left": 0, "top": 0, "width": 1, "height": 0.35 },
{ "id": "line_items", "label": "Line Items/Table", "left": 0, "top": 0.28, "width": 1, "height": 0.5 },
{ "id": "totals", "label": "Totals", "left": 0.45, "top": 0.7, "width": 0.55, "height": 0.3 }
],
"fields": [
{ "key": "merchant_name", "type": "string", "required": true },
{ "key": "transaction_date", "type": "date", "required": true },
{ "key": "total", "type": "currency", "required": true }
],
"validation_rules": {
"arithmetic": true,
"amount_tolerance": 0.05
}
},
"template_json": {
"schema_version": "1.0"
},
"sample_receipt": {
"merchant_name": "Kasikornbank",
"transaction_date": "2026-01-14",
"total": 786
},
"provider": {
"model": "gpt-5.1",
"source": "openai_vision"
},
"created_at": "2026-03-01T00:26:29.478Z",
"updated_at": "2026-03-01T00:26:29.478Z"
}
  • template_json mirrors normalized_template and is returned as a compatibility alias.

Error responses

  • 400 missing template_id.
  • 401 invalid API key.
  • 404 template does not exist or does not belong to this API key.

JavaScript SDK (samsar-js)

import SamsarClient from 'samsar-js';

const samsar = new SamsarClient({ apiKey: process.env.SAMSAR_API_KEY! });

const templateJson = await samsar.getReceiptTemplateJson(
'receipt_tpl_0e4f9f1dca744ec9b3a3f8df',
);

console.log(templateJson.data.template_json);

GET /image/status

Check the latest state for a single image request (accepts request_id or session_id).

curl "https://api.samsar.one/v1/image/status?request_id=img_enh_123" \
-H "Authorization: Bearer $SAMSAR_API_KEY"

Queued / processing

{
"session_id": "img_enh_123",
"request_id": "img_enh_123",
"status": "PENDING",
"type": "image",
"provider": "NANOBANANA2",
"case_type": "image_enhance"
}

Completed

{
"session_id": "img_enh_123",
"request_id": "img_enh_123",
"status": "COMPLETED",
"type": "image",
"provider": "NANOBANANA2",
"case_type": "image_enhance",
"result_url": "https://cdn.samsar.one/images/img_enh_123.png"
}
  • result_urls is present when multiple assets are produced.
  • thumbnail_url is included for rollup banner completions and points to a downscaled preview.
  • A 404 is returned if the request does not belong to your API key or is unknown.

GET /image/list

Fetch a list of your recent image API sessions, including their current status and any available results. Use limit (max 500) to trim the response.

curl "https://api.samsar.one/v1/image/list?limit=50" \
-H "Authorization: Bearer $SAMSAR_API_KEY"

Response (200)

{
"sessions": [
{
"session_id": "img_rm_123",
"request_id": "img_rm_123",
"status": "COMPLETED",
"type": "image",
"provider": "NANOBANANA2",
"case_type": "logo_remove",
"request_type": "API",
"result_url": "https://cdn.samsar.one/images/img_rm_123.png",
"created_at": "2024-08-20T08:10:11.000Z",
"updated_at": "2024-08-20T08:12:42.000Z"
},
{
"session_id": "img_set_987",
"request_id": "img_set_987",
"status": "PENDING",
"type": "image",
"provider": "NANOBANANA2",
"case_type": "image_list_to_image_set",
"request_type": "API",
"created_at": "2024-08-20T08:15:55.000Z",
"updated_at": "2024-08-20T08:15:55.000Z"
}
]
}

Common errors

  • 400 invalid or missing fields (empty URLs, bad resolution, non-numeric num_images).
  • 401 invalid API key.
  • 402 insufficient credits.
  • 404 unknown request_id (or a request that does not belong to the API key on /image/status).

Utils

POST /image/create_rollup_banner_with_enhance

Enhance low-resolution tiles (if needed) and generate a rollup banner. Images below the rollup minimum (2020x2526) are auto-upscaled using 1k/2k/4k, then the list is expanded to 28 tiles before rendering.

Request body

{
"images": [
{
"image_url": "https://cdn.example.com/tile-1.png",
"image_text": "Rooftop Bar",
"image_category": "Social",
"overlay": { "top_left": "2 hours", "top_right": "City", "footer": "Rooftop Bar" }
}
],
"header_image_url": "https://cdn.example.com/header.png",
"footer_image_url": "https://cdn.example.com/footer.png",
"columns": 4,
"max_tiles": 28,
"image_tiling_position": {
"font_key": "en",
"font_family": "Poppins, Helvetica, Arial, sans-serif",
"top_left": {
"margin_min": 28,
"margin_ratio": 0.02,
"diameter_min": 220,
"diameter_max": 320,
"diameter_ratio": 0.215,
"inner_padding_min": 12,
"inner_padding_ratio": 0.08
},
"top_right": {
"margin_min": 28,
"margin_ratio": 0.02,
"max_width_floor": 260,
"min_width": 220,
"padding_left": 36,
"padding_right": 48,
"padding_top": 30,
"padding_bottom": 24,
"overlay_height_min": 140
},
"bottom": {
"inset_min": 32,
"inset_ratio": 0.03,
"offset_min": 12,
"offset_ratio": 0.02,
"container_margin_min": 40,
"container_margin_ratio": 0.08,
"text_inset_min": 18,
"text_inset_ratio": 0.04,
"overlay_height_min": 280
}
}
}
  • images (or image_list/image_urls) required, non-empty array.
  • Items accept image_url (or enhanced_url) plus optional image_text, image_category, image_duration, overlay.
  • columns optional integer 1-6; defaults to 4.
  • max_tiles optional integer; defaults to 28.
  • header_image_url and footer_image_url optional.
  • image_tiling_position optional object for tile overlay layout and font overrides. Omit to use defaults.

image_tiling_position (optional)

Overrides for per-tile overlay placement and font selection. You can send only the fields you want to change.

  • font_key required if provided; must match a supported subtitle language key (e.g., en, fr, es, ja, ko, zh-cn, zh-tw, hi, ar).
  • font_family optional; comma-separated stack. The first font must be supported for the chosen font_key.
  • top_left optional object for the circular badge.
    • margin_min, margin_ratio
    • diameter_min, diameter_max, diameter_ratio
    • inner_padding_min, inner_padding_ratio
  • top_right optional object for the top-right label.
    • margin_min, margin_ratio
    • max_width_floor, min_width
    • padding_left, padding_right, padding_top, padding_bottom
    • overlay_height_min
  • bottom optional object for the footer label.
    • inset_min, inset_ratio
    • offset_min, offset_ratio
    • container_margin_min, container_margin_ratio
    • text_inset_min, text_inset_ratio
    • overlay_height_min

All *_ratio values are fractions between 0 and 1. Values are validated; invalid ranges return 400.

Success response (200)

{
"status": "completed",
"session_id": "rollup_enh_123",
"request_id": "rollup_enh_123",
"rollup_session_id": "rollup_456",
"rollup_request_id": "rollup_456",
"case_type": "rollup_banner_enhance",
"result_url": "https://cdn.samsar.one/rollups/rollup_456.png",
"thumbnail_url": "https://cdn.samsar.one/rollups/rollup_456-thumb.png",
"result_urls": ["https://cdn.samsar.one/rollups/rollup_456.png"],
"input_image_urls": [
"https://cdn.example.com/tile-1-enhanced.png"
],
"creditsCharged": 180,
"remainingCredits": 4820
}

Poll /image/status?request_id=rollup_enh_123 for completion. The status payload includes case_type: rollup_banner_enhance. input_image_urls returns the enhanced URLs used for the rollup request (falls back to original URLs when no enhancement was needed), before any duplication to 28 tiles.

POST /image/create_rollup_banner

Generate a rollup banner image from a list of tiles, with optional header/footer imagery.

Request body

{
"image_list": [
{
"image_url": "https://cdn.example.com/tile-1.png",
"title": "Rooftop Bar",
"image_category": "Social",
"image_duration": "2 hours"
},
{
"enhanced_url": "https://cdn.example.com/tile-2.png",
"overlay": { "top_left": "Half day", "top_right": "Pool", "footer": "Cabana" }
}
],
"header_image_url": "https://cdn.example.com/header.png",
"footer_image_url": "https://cdn.example.com/footer.png",
"columns": 4,
"max_tiles": 28,
"image_tiling_position": {
"font_key": "en",
"font_family": "Poppins, Helvetica, Arial, sans-serif",
"top_left": {
"margin_min": 28,
"margin_ratio": 0.02,
"diameter_min": 220,
"diameter_max": 320,
"diameter_ratio": 0.215,
"inner_padding_min": 12,
"inner_padding_ratio": 0.08
},
"top_right": {
"margin_min": 28,
"margin_ratio": 0.02,
"max_width_floor": 260,
"min_width": 220,
"padding_left": 36,
"padding_right": 48,
"padding_top": 30,
"padding_bottom": 24,
"overlay_height_min": 140
},
"bottom": {
"inset_min": 32,
"inset_ratio": 0.03,
"offset_min": 12,
"offset_ratio": 0.02,
"container_margin_min": 40,
"container_margin_ratio": 0.08,
"text_inset_min": 18,
"text_inset_ratio": 0.04,
"overlay_height_min": 280
}
}
}
  • image_list (or images) required, non-empty array. Each item must include image_url or enhanced_url.
  • overlay optional; supports top_left, top_right, footer (fallbacks: title, image_text, image_category, image_duration).
  • columns optional integer 1-6; defaults to 4.
  • max_tiles optional integer; defaults to 28.
  • header_image_url and footer_image_url optional.
  • image_tiling_position optional object for tile overlay layout and font overrides. Omit to use defaults.

image_tiling_position (optional)

Same schema and validation as /image/create_rollup_banner_with_enhance. See details above.

Success response (200)

{
"status": "completed",
"session_id": "rollup_123",
"request_id": "rollup_123",
"result_url": "https://cdn.samsar.one/rollups/rollup_123.png",
"thumbnail_url": "https://cdn.samsar.one/rollups/rollup_123-thumb.png",
"result_urls": ["https://cdn.samsar.one/rollups/rollup_123.png"],
"creditsCharged": 30,
"remainingCredits": 4970
}