Lập trình viên

gimgs API

Dùng các công cụ AI của Photosoft ngay trong code của bạn: tách nền và phóng to ảnh qua REST API, tính phí theo ảnh từ số dư Point.

Tài liệu kỹ thuật bên dưới bằng tiếng Anh.

Quick start

Base URL: https://gimgs.net/api/v1. One request uploads the image and starts a job; add wait to block until it is done (up to 60 s), then download the result.

# 1. remove the background and wait for the result (returns JSON with result_url)
curl -X POST "https://gimgs.net/api/v1/remove-bg?wait=60" \
  -H "Authorization: Bearer gk_YOUR_KEY" \
  -F "image=@photo.jpg"

# 2. save the transparent PNG
curl -L -o cutout.png "https://tmp.gimgs.net/u/you/editor/ai_rmbg_….png"

# upscale 4× from a URL instead of a file
curl -X POST "https://gimgs.net/api/v1/upscale" \
  -H "Authorization: Bearer gk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"image_url":"https://example.com/small.png","scale":4,"wait":60}'

Without wait the call returns 202 immediately with "status":"queued"; poll GET /jobs/{id} until status is completed or failed.

Authentication

Every call except the public ones needs an API key. Create up to 5 keys in your account → API keys; a key is shown once when created and starts with gk_. Send it in the Authorization header (or as X-Api-Key):

Authorization: Bearer gk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Keep keys on the server side. A key spends the Point balance of the account that created it. Revoking a key in your account stops it within a few minutes.

Pricing

Every image processed through the API is charged in Point from the balance of the account that owns the key when the job is accepted:

TaskPrice
Remove background0.1 Point per image
Upscale 2×0.1 Point per image
Upscale 4×0.15 Point per image
  • The free daily images of the Photosoft editor (10 per day, 100 for VIP) are not used by the API — API calls never touch that quota, and VIP accounts pay the same per-image price.
  • A job that fails is refunded automatically; the response then shows "refunded": true.
  • Nothing is charged for requests rejected before a job starts (invalid image, too many jobs, queue error).
  • GET /me shows the balance, the price of each task and how many images it covers at the lowest price; each job response carries a billing object with what was charged.

Sending images

JPG, PNG or WebP up to 20 MB. The format is detected from the file bytes, not from the Content-Type. Three ways to send:

multipart/form-data
file field image (or file); other options (scale, wait) as ordinary form fields.
application/json
{"image_url": "https://…"} — the server downloads it (public http(s) URL, 15 s timeout) — or {"image_base64": "…"} (a data URL works too).
raw body
the image bytes with Content-Type: image/png, image/jpeg or image/webp; options go in the query string (?scale=4&wait=30).

Endpoints

MethodPathAuthWhat it does
GET/api/v1/meAPI keyAccount: plan, Point balance and price per image
POST/api/v1/remove-bgAPI keyRemove the background of an image (transparent PNG)
POST/api/v1/upscaleAPI keyUpscale an image 2× or 4×
GET/api/v1/jobs/{id}API keyJob status and result URL (supports ?wait=)
GET/api/v1/jobs/{id}/resultAPI keyDownload the result image
GET/api/v1/taskspublicPricing and input limits
GET/api/v1/openapi.jsonpublicOpenAPI 3.1 description of this API
GET/api/v1/meAPI key

Who the key belongs to, VIP status, Point balance, price per image and how many images the balance covers.

{
  "uname": "alice",
  "is_vip": false,
  "balance": 2.5,
  "currency": "Point",
  "cost_per_image": 0.1,
  "images_affordable": 25
}
POST/api/v1/remove-bgAPI key

Removes the background and returns a PNG with transparency. Body: the image (see Sending images); optional wait.

// 202 Accepted (no wait) — or 200 with status completed when wait was given
{
  "id": "0b1f0b4e-6b9c-4a1e-9d2a-2f3c7d9f8e10",
  "task": "remove-bg",
  "status": "queued",
  "progress": 0,
  "message": "Queued",
  "result_url": null,
  "download_url": null,
  "cost": 0.1,
  "refunded": false,
  "created_at": "2026-10-09 14:02:11",
  "updated_at": "2026-10-09 14:02:11",
  "billing": { "cost": 0.1, "balance": 2.4, "currency": "Point" }
}
POST/api/v1/upscaleAPI key

Upscales the image. Option scale: 2 (default) or 4; 4× needs the longest side ≤ 4096 px (422 invalid_image otherwise — use 2×). Same response shape as remove-bg with "task": "upscale-2x" / "upscale-4x".

GET/api/v1/jobs/{id}API key

Status of one of your jobs. Add ?wait=N (≤ 60) to long-poll: the response is sent as soon as the job finishes or after N seconds, whichever comes first.

{
  "id": "0b1f0b4e-6b9c-4a1e-9d2a-2f3c7d9f8e10",
  "task": "remove-bg",
  "status": "completed",
  "progress": 100,
  "message": "Done",
  "result_url": "https://tmp.gimgs.net/u/alice/editor/ai_rmbg_0b1f0b4e.png",
  "download_url": "https://gimgs.net/api/v1/jobs/0b1f0b4e-6b9c-4a1e-9d2a-2f3c7d9f8e10/result",
  "cost": 0.1,
  "refunded": false,
  "created_at": "2026-10-09 14:02:11",
  "updated_at": "2026-10-09 14:02:48"
}
GET/api/v1/jobs/{id}/resultAPI key

The result image itself, streamed through the API (handy when your client cannot fetch result_url directly). ?download=1 adds Content-Disposition: attachment. Returns 409 job_not_ready while the job is running and 409 job_failed if it failed.

GET/api/v1/taskspublic

Public pricing and input limits as JSON — useful to display in your own UI.

Jobs & polling

  • Lifecycle: queued → processing → completed | failed. progress is 0–100, message is the worker's last note.
  • Typical duration: remove background 20–60 s, upscale 30–120 s depending on size. Poll every 3–5 s, or use wait and poll again if the response still says processing.
  • Jobs are processed in a background worker; a job stuck for more than a few minutes is marked failed and refunded automatically.
  • result_url is a public, CORS-enabled URL on tmp.gimgs.net. Treat it as temporary and copy the file to your own storage.
  • Only the account that created a job can read it; other accounts get 404.

Errors

Errors are JSON with an error object; the HTTP status tells you how to react.

{ "error": { "code": "insufficient_balance", "message": "Insufficient balance", "required": 0.1, "balance": 0.05 } }
StatuscodeMeaning
400bad_requestMalformed JSON or form body.
401unauthorized / invalid_keyMissing, malformed or revoked API key.
402insufficient_balanceNot enough Point for this image. required and balance are included.
403account_not_foundThe account behind the key no longer exists.
404not_foundUnknown endpoint, or a job that is not yours.
409job_not_ready / job_failed/result called before the job finished, or the job failed.
413file_too_largeImage over 20 MB.
415unsupported_media_typeRequest Content-Type is not one of the accepted ones.
422missing_image, invalid_image, invalid_image_url, image_url_unreachable, invalid_requestNo image, unsupported format, URL could not be downloaded, bad scale, 4× image over 4096 px.
429too_many_jobsMore than 5 jobs running at once for this account. Wait and retry (Retry-After header).
502queue_errorThe job could not be queued; nothing was charged. Retry.
503billing_unavailable / unavailableAccount or billing service busy. Retry with back-off.

Limits

  • Image: JPG / PNG / WebP, ≤ 20 MB; 4× upscale ≤ 4096 px on the longest side.
  • At most 5 jobs running at the same time per account (429 beyond that).
  • wait ≤ 60 s per request; image_url download timeout 15 s.
  • Up to 5 API keys per account.
  • CORS is enabled (Access-Control-Allow-Origin: *) so browser apps can call the API, but do not ship your key to browsers.

Code examples

JavaScript (Node 18+ / Deno / Bun / browsers)

const KEY = process.env.GIMGS_API_KEY;
const BASE = "https://gimgs.net/api/v1";

async function removeBackground(file) {            // file: Blob / File
  const fd = new FormData();
  fd.append("image", file, "photo.png");
  fd.append("wait", "60");
  const res = await fetch(BASE + "/remove-bg", { method: "POST", headers: { Authorization: "Bearer " + KEY }, body: fd });
  let job = await res.json();
  if (!res.ok) throw new Error(job.error.code + ": " + job.error.message);
  while (job.status !== "completed" && job.status !== "failed") {      // still running after 60 s? keep polling
    const r = await fetch(BASE + "/jobs/" + job.id + "?wait=30", { headers: { Authorization: "Bearer " + KEY } });
    job = await r.json();
  }
  if (job.status === "failed") throw new Error(job.message);
  return job.result_url;                               // https://tmp.gimgs.net/u/…/ai_rmbg_….png
}

Python

import os, time, requests

KEY = os.environ["GIMGS_API_KEY"]
BASE = "https://gimgs.net/api/v1"
H = {"Authorization": f"Bearer {KEY}"}

def upscale(path, scale=2):
    with open(path, "rb") as f:
        r = requests.post(f"{BASE}/upscale", headers=H, files={"image": f}, data={"scale": scale, "wait": 60})
    job = r.json()
    if not r.ok:
        raise RuntimeError(job["error"])
    while job["status"] not in ("completed", "failed"):
        job = requests.get(f"{BASE}/jobs/{job['id']}", headers=H, params={"wait": 30}).json()
    if job["status"] == "failed":
        raise RuntimeError(job["message"])
    img = requests.get(job["result_url"]).content
    open("upscaled.png", "wb").write(img)
    return job

print(upscale("small.jpg", scale=4)["billing"])

curl, step by step

# account + balance
curl "https://gimgs.net/api/v1/me" -H "Authorization: Bearer gk_YOUR_KEY"

# raw body upload, no waiting
curl -X POST "https://gimgs.net/api/v1/remove-bg" -H "Authorization: Bearer gk_YOUR_KEY" \
  -H "Content-Type: image/jpeg" --data-binary @photo.jpg
# → 202 {"id":"…","status":"queued",…}

# poll (long-poll up to 30 s)
curl "https://gimgs.net/api/v1/jobs/JOB_ID?wait=30" -H "Authorization: Bearer gk_YOUR_KEY"

# download through the API
curl -o cutout.png "https://gimgs.net/api/v1/jobs/JOB_ID/result?download=1" -H "Authorization: Bearer gk_YOUR_KEY"

Want another Photosoft tool in the API? Tell us from the contribute page.