Приклади
Повні приклади інтеграції з використанням curl, JavaScript та Python.
На цій сторінці представлено повний робочий процес генерації фотосесії трьома мовами: curl, JavaScript (fetch) та Python (requests). Кожен приклад виконує однакові кроки:
- Перегляд продуктів для вибору одного для зйомки.
- Перегляд схвалених ШІ-моделей та декорацій.
- Реєстрація генерації фотосесії з комбінацією продукту, моделі та декорації.
- Опитування ендпоінта image-picker до готовності результатів.
- Перегляд та схвалення згенерованих зображень.
Загальне налаштування
Кожен запит вимагає дві речі:
- Базова URL-адреса —
https://qamera.ai(замініть на вашу власну URL-адресу для self-hosted розгортань). - Автентифікація — Передайте ваш API key у заголовку
X-Api-Key.
X-Api-Key: mk_live_abc123.secret456
Ви можете згенерувати API key у Settings > API Keys вашого командного робочого простору. Ключ показується лише один раз, тому скопіюйте його негайно.
GET-ендпоінти безкоштовні та ніколи не витрачають кредити. POST-ендпоінти, що запускають генерацію контенту, резервують кредити наперед і витрачають їх після завершення обробки.
Приклади curl
Крок 1 — Перегляд продуктів
Отримайте всі продукти, завантажені до вашого акаунта.
curl -s -X GET "https://qamera.ai/api/external/products" \ -H "X-Api-Key: mk_live_abc123.secret456"
Відповідь:
{
"products": [
{
"id": "rec_product_001",
"name": "White T-Shirt Front",
"thumbnail": "https://cdn.example.com/products/thumb_001.jpg",
"status": "UPLOADED",
"createdAt": "2026-03-20T14:30:00.000Z"
},
{
"id": "rec_product_002",
"name": "Leather Handbag",
"thumbnail": "https://cdn.example.com/products/thumb_002.jpg",
"status": "UPLOADED",
"createdAt": "2026-03-21T09:15:00.000Z"
}
],
"count": 2
}
Виберіть ID продукту для використання у фотосесії. У цих прикладах ми будемо використовувати rec_product_001.
Крок 2 — Перегляд схвалених моделей
Отримайте лише моделі, схвалені для використання.
curl -s -X GET "https://qamera.ai/api/external/models?statusFilter=approved" \ -H "X-Api-Key: mk_live_abc123.secret456"
Відповідь:
{
"models": [
{
"id": "rec_model_101",
"name": "Sophie — Casual",
"thumbnail": "https://cdn.example.com/models/thumb_101.jpg",
"status": "DONE",
"voting": "APPROVED",
"createdAt": "2026-03-18T10:00:00.000Z"
}
],
"count": 1
}
Крок 3 — Перегляд схвалених декорацій
curl -s -X GET "https://qamera.ai/api/external/sceneries?statusFilter=approved" \ -H "X-Api-Key: mk_live_abc123.secret456"
Відповідь:
{
"sceneries": [
{
"id": "rec_scenery_201",
"name": "Bright Studio",
"thumbnail": "https://cdn.example.com/sceneries/thumb_201.jpg",
"status": "DONE",
"voting": "APPROVED",
"createdAt": "2026-03-19T11:45:00.000Z"
}
],
"count": 1
}
Крок 4 — Реєстрація фотосесії
Скомбінуйте продукт, модель та декорацію для запуску генерації. Цей ендпоінт резервує кредити.
curl -s -X POST "https://qamera.ai/api/external/image-picker/register-ideas" \
-H "X-Api-Key: mk_live_abc123.secret456" \
-H "Content-Type: application/json" \
-d '{
"config": {
"product": { "id": "rec_product_001" },
"model": { "id": "rec_model_101" },
"scenery": { "id": "rec_scenery_201" },
"industry": "fashion",
"suggestions": "bright lighting, clean composition"
},
"count": 4
}'
Відповідь:
{
"createdRecordIds": ["rec_gen_301", "rec_gen_302", "rec_gen_303", "rec_gen_304"],
"batchId": "batch_abc123",
"orderId": "ord_xyz789",
"reservationId": "res_def456",
"creditsReserved": 120
}
Збережіть createdRecordIds — ви будете використовувати їх для перевірки прогресу.
Крок 5 — Опитування результатів
Генерація відбувається асинхронно. Опитуйте ендпоінт image-picker, фільтруючи за вашим продуктом, поки зображення не отримають статус DONE.
curl -s -X GET "https://qamera.ai/api/external/image-picker?productId=rec_product_001" \ -H "X-Api-Key: mk_live_abc123.secret456"
Відповідь (під час обробки):
{
"images": [
{
"id": "rec_gen_301",
"name": "White T-Shirt — Variant 1",
"thumbnail": "",
"status": "INPROGRESS",
"voting": null,
"createdAt": "2026-03-27T12:00:00.000Z"
}
],
"count": 1
}
Зачекайте хвилину та викличте той самий ендпоінт знову. Коли status стане DONE, поле thumbnail міститиме URL зображення.
Крок 6 — Схвалення або відхилення результатів
Ви можете схвалювати зображення за допомогою ендпоінта оновлення пакшотів. Для зображень фотосесії, які ви хочете зберегти, схваліть їх, щоб вони з'являлися у відфільтрованих переглядах.
# Схвалення зображення
curl -s -X POST "https://qamera.ai/api/external/packshots/update-packshot" \
-H "X-Api-Key: mk_live_abc123.secret456" \
-H "Content-Type: application/json" \
-d '{
"recordId": "rec_gen_301",
"Voting": "APPROVED"
}'
Відповідь:
{
"success": true,
"message": "Packshot voting updated successfully",
"recordId": "rec_gen_301"
}
Для відхилення зображення (яке архівує його):
curl -s -X POST "https://qamera.ai/api/external/packshots/update-packshot" \
-H "X-Api-Key: mk_live_abc123.secret456" \
-H "Content-Type: application/json" \
-d '{
"recordId": "rec_gen_302",
"Voting": "REJECTED"
}'
Приклад JavaScript (fetch)
Наступний приклад використовує API fetch браузера/Node.js для виконання того самого робочого процесу.
Допоміжна функція
const BASE_URL = "https://qamera.ai";
const API_KEY = "mk_live_abc123.secret456";
async function qameraFetch(path, options = {}) {
const url = new URL(path, BASE_URL);
if (options.params) {
Object.entries(options.params).forEach(([key, value]) =>
url.searchParams.set(key, value)
);
}
const response = await fetch(url.toString(), {
method: options.method || "GET",
headers: {
"X-Api-Key": API_KEY,
...(options.body ? { "Content-Type": "application/json" } : {}),
},
...(options.body ? { body: JSON.stringify(options.body) } : {}),
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(
`API error ${response.status}: ${error.error || response.statusText}`
);
}
return response.json();
}
Повний робочий процес
async function runPhotoShootWorkflow() {
// 1. Перегляд продуктів
const { products } = await qameraFetch("/api/external/products");
console.log(`Found ${products.length} products`);
const product = products[0];
if (!product) throw new Error("No products found. Upload one first.");
console.log(`Using product: ${product.name} (${product.id})`);
// 2. Перегляд схвалених моделей
const { models } = await qameraFetch("/api/external/models", {
params: { statusFilter: "approved" },
});
console.log(`Found ${models.length} approved models`);
// 3. Перегляд схвалених декорацій
const { sceneries } = await qameraFetch("/api/external/sceneries", {
params: { statusFilter: "approved" },
});
console.log(`Found ${sceneries.length} approved sceneries`);
// 4. Реєстрація генерації фотосесії
const registration = await qameraFetch(
"/api/external/image-picker/register-ideas",
{
method: "POST",
body: {
config: {
product: { id: product.id },
model: models[0] ? { id: models[0].id } : undefined,
scenery: sceneries[0] ? { id: sceneries[0].id } : undefined,
industry: "fashion",
suggestions: "bright lighting, clean composition",
},
count: 4,
},
}
);
console.log(`Generation started — order ${registration.orderId}`);
console.log(`Credits reserved: ${registration.creditsReserved}`);
// 5. Опитування до готовності результатів
const generatedIds = new Set(registration.createdRecordIds);
let attempts = 0;
const maxAttempts = 30;
while (attempts < maxAttempts) {
await new Promise((resolve) => setTimeout(resolve, 10_000));
attempts++;
const { images } = await qameraFetch("/api/external/image-picker", {
params: { productId: product.id },
});
const ours = images.filter((img) => generatedIds.has(img.id));
const done = ours.filter((img) => img.status === "DONE");
console.log(`Poll ${attempts}: ${done.length}/${ours.length} done`);
if (done.length === ours.length && done.length > 0) {
console.log("All images ready!");
// 6. Схвалення першого результату
await qameraFetch("/api/external/packshots/update-packshot", {
method: "POST",
body: {
recordId: done[0].id,
Voting: "APPROVED",
},
});
console.log(`Approved image ${done[0].id}`);
return done;
}
}
throw new Error("Generation timed out after 5 minutes");
}
runPhotoShootWorkflow()
.then((images) => console.log("Completed:", images))
.catch((err) => console.error("Failed:", err.message));
Приклад Python (requests)
Наступний приклад використовує бібліотеку requests (pip install requests).
Налаштування сесії
import time
import requests
BASE_URL = "https://qamera.ai"
API_KEY = "mk_live_abc123.secret456"
session = requests.Session()
session.headers.update({"X-Api-Key": API_KEY})
Повний робочий процес
def run_photo_shoot_workflow():
# 1. Перегляд продуктів
resp = session.get(f"{BASE_URL}/api/external/products")
resp.raise_for_status()
products = resp.json()["products"]
print(f"Found {len(products)} products")
if not products:
raise RuntimeError("No products found. Upload one first.")
product = products[0]
print(f"Using product: {product['name']} ({product['id']})")
# 2. Перегляд схвалених моделей
resp = session.get(
f"{BASE_URL}/api/external/models",
params={"statusFilter": "approved"},
)
resp.raise_for_status()
models = resp.json()["models"]
print(f"Found {len(models)} approved models")
# 3. Перегляд схвалених декорацій
resp = session.get(
f"{BASE_URL}/api/external/sceneries",
params={"statusFilter": "approved"},
)
resp.raise_for_status()
sceneries = resp.json()["sceneries"]
print(f"Found {len(sceneries)} approved sceneries")
# 4. Реєстрація генерації фотосесії
config = {
"product": {"id": product["id"]},
"industry": "fashion",
"suggestions": "bright lighting, clean composition",
}
if models:
config["model"] = {"id": models[0]["id"]}
if sceneries:
config["scenery"] = {"id": sceneries[0]["id"]}
resp = session.post(
f"{BASE_URL}/api/external/image-picker/register-ideas",
json={"config": config, "count": 4},
)
resp.raise_for_status()
registration = resp.json()
print(f"Generation started — order {registration['orderId']}")
print(f"Credits reserved: {registration['creditsReserved']}")
# 5. Опитування до готовності результатів
generated_ids = set(registration["createdRecordIds"])
max_attempts = 30
for attempt in range(1, max_attempts + 1):
time.sleep(10)
resp = session.get(
f"{BASE_URL}/api/external/image-picker",
params={"productId": product["id"]},
)
resp.raise_for_status()
images = resp.json()["images"]
ours = [img for img in images if img["id"] in generated_ids]
done = [img for img in ours if img["status"] == "DONE"]
print(f"Poll {attempt}: {len(done)}/{len(ours)} done")
if len(done) == len(ours) and done:
print("All images ready!")
# 6. Схвалення першого результату
resp = session.post(
f"{BASE_URL}/api/external/packshots/update-packshot",
json={
"recordId": done[0]["id"],
"Voting": "APPROVED",
},
)
resp.raise_for_status()
print(f"Approved image {done[0]['id']}")
return done
raise TimeoutError("Generation timed out after 5 minutes")
if __name__ == "__main__":
try:
results = run_photo_shoot_workflow()
for img in results:
print(f" {img['name']}: {img['thumbnail']}")
except Exception as e:
print(f"Error: {e}")