Przegląd
Endpoint POST /api/v1/remove-bg przyjmuje zdjęcie produktu, usuwa tło, kadruje (fill ratio) i zwraca URL wyniku. Debet kredytu następuje tylko przy sukcesie.
Bearer API key
cbg_live_… lub cbg_test_…
1 kredyt / sukces
Błędy AI nie debitują salda
Rate limit
30 req/min na klucz, 60/min na IP
Autoryzacja
Każdy request wymaga nagłówka Authorization. Klucz tworzysz w Dashboard → API Keys. Pełny sekret widzisz tylko raz przy utworzeniu.
Authorization: Bearer cbg_live_xxxxxxxxxxxxxxxxNigdy nie commituj kluczy do repozytorium. Używaj zmiennych środowiskowych. Prefiks cbg_test_ / cbg_live_ zależy od środowiska.
Endpoint
https://crystalcut.pl/api/v1/remove-bgContent-Type: application/json· Timeout po stronie klienta: zalecane ≥ 90–120 s
Parametry wejściowe
Wymagane jest image_url albo image_b64 (co najmniej jedno).
| Pole | Typ | Domyślnie | Opis |
|---|---|---|---|
| image_url | string (URL) | — | Publiczny HTTPS URL zdjęcia (preferowane) |
| image_b64 | string | — | Surowe base64 (bez prefiksu data:). Max ~12 MB |
| fill_ratio | number | 0.88 | Wypełnienie kadru produktem (0.5–1.0) |
| canvas_size | integer | 1024 | Bok kwadratu wynikowego w px (512–2048) |
Przykłady
Zamień klucz i URL na własne wartości.
cURL
curl -X POST https://crystalcut.pl/api/v1/remove-bg \
-H "Authorization: Bearer cbg_live_TWOJ_KLUCZ" \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://example.com/product.jpg",
"fill_ratio": 0.88,
"canvas_size": 1024
}'JavaScript (fetch)
const res = await fetch("https://crystalcut.pl/api/v1/remove-bg", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CRYSTALCUT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
image_url: "https://example.com/product.jpg",
fill_ratio: 0.88,
canvas_size: 1024,
}),
});
const data = await res.json();
if (data.status === "success") {
console.log(data.image_url, data.credits_remaining);
} else {
console.error(data.code, data.message);
}Python
import os
import requests
API_KEY = os.environ["CRYSTALCUT_API_KEY"]
url = "https://crystalcut.pl/api/v1/remove-bg"
payload = {
"image_url": "https://example.com/product.jpg",
"fill_ratio": 0.88,
"canvas_size": 1024,
}
r = requests.post(
url,
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json=payload,
timeout=120,
)
data = r.json()
if data.get("status") == "success":
print(data["image_url"], data.get("credits_remaining"))
else:
print(data.get("code"), data.get("message"))Odpowiedzi
Success
{
"status": "success",
"id": "clxgeneration123",
"image_url": "https://cdn.example.com/out/processed.jpg",
"fill_ratio": 0.88,
"canvas_size": 1024,
"credits_remaining": 42
}Unauthorized
{
"status": "error",
"code": "INVALID_API_KEY",
"message": "Invalid or revoked API key"
}Payment Required
{
"status": "error",
"code": "NO_CREDITS",
"message": "Insufficient credits. Purchase a pack or subscription.",
"credits_remaining": 0
}Too Many Requests
{
"status": "error",
"code": "RATE_LIMIT",
"message": "API key rate limit exceeded. Try again later.",
"remaining": 0,
"reset": 1730000060
}Nagłówki: Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Processing / Internal error
{
"status": "error",
"code": "PROCESSING_FAILED",
"message": "Processing failed on RunPod",
"id": "clxgeneration123"
}Przy PROCESSING_FAILED kredyt nie jest odejmowany.
Kody błędów
Format zawsze: { "status": "error", "code": "…", "message": "…" }
| HTTP | code | Znaczenie |
|---|---|---|
| 400 | INVALID_REQUEST | Błędne body (Zod) / brak image_url i image_b64 |
| 401 | MISSING_API_KEY | Brak nagłówka Authorization: Bearer … |
| 401 | INVALID_API_KEY | Klucz nieprawidłowy lub unieważniony |
| 402 | NO_CREDITS | Brak kredytów na koncie |
| 429 | RATE_LIMIT | Przekroczony limit (klucz lub IP) |
| 500 | PROCESSING_FAILED | Błąd RunPod / AI — bez debitu |
| 500 | INTERNAL_ERROR | Nieoczekiwany błąd serwera |
| 503 | SERVICE_UNAVAILABLE | Usługa przetwarzania nie skonfigurowana |
Limity i uwagi
- Rate limit: domyślnie 30 requestów / minutę na klucz API oraz 60 / minutę na IP.
- Kredyty: 1 sukces = 1 kredyt. FAILED nie debituje.
- Preferuj
image_urlzamiast dużego base64 (szybsze i lżejsze). - Maks. canvas: 2048 px.
- Retencja: przetworzone obrazy mogą być usuwane po 30 dniach (GDPR).
OpenAPI
Specyfikacja OpenAPI 3.1 jest dostępna publicznie — możesz zaimportować ją do Postmana, Insomnii lub wygenerować klienta.
# Pobierz spec
curl -s https://crystalcut.pl/openapi.json | head
# Lub dynamicznie
curl -s https://crystalcut.pl/api/openapi | head