Отримання результатів
Вебхуки з підписом HMAC, повтори та повторне надсилання, опитування як альтернатива й оновлення прострочених адрес для завантаження.
Що ви отримаєте
Генерація асинхронна — ви надсилаєте сесію, а результати надходять за кілька десятків секунд або хвилин. У цьому матеріалі ви налаштуєте приймання вебхуків (з перевіркою підпису), дізнаєтеся про опитування як простішу альтернативу й навчитеся оновлювати прострочені адреси для завантаження.
Передумови
- Ключ API інсталяції (як його отримати) з дозволом
plugin.jobs:read(для опитування) таplugin.webhooks:manage(для повторного надсилання вебхуків). - Для вебхуків: публічно доступна адреса HTTPS вашого плагіна, встановлена як
callback_urlінсталяції, та секрет HMAC інсталяції.
Перебіг
вебхук (push) GET /jobs/{id} (pull)
├─ перевірте підпис HMAC ├─ перевіряйте статус
├─ відповідайте 2xx └─ завантажте outputs[].url
└─ завантажте outputs[].url
адреса прострочена? → POST /jobs/{id}/refresh-url
неотриманий вебхук? → POST /webhooks/{delivery_id}/replay
Кроки — вебхуки
1. Прийміть сповіщення
Коли завдання досягає кінцевого стану, ми надсилаємо POST на callback_url вашої інсталяції. Поле event набуває значень job.completed, job.failed або job.cancelled.
{
"event": "job.completed",
"delivered_at": "2026-06-03T08:00:00.000Z",
"job": {
"id": "00000000-0000-0000-0000-0000000000a1",
"status": "completed",
"order_id": "00000000-0000-0000-0000-000000000099",
"completed_at": "2026-06-03T07:59:40.000Z",
"error": null
},
"outputs": [
{
"url": "https://…?token=…",
"type": "image/jpeg",
"width": 1024,
"height": 1280
}
],
"external_metadata": { "sku": "SKU-001" }
}
Поле external_metadata повертається точно таким, яким ви його надіслали під час створення сесії — використайте його, щоб зіставити результат зі своїм замовленням (наприклад, впишіть туди ID продукту зі свого магазину).
2. Перевірте підпис
Кожне сповіщення має заголовок:
X-Qamera-Signature: t=<час-unix>,v1=<hmac_sha256_hex>
Підписується рядок <t>.<сире-body> секретом HMAC вашої інсталяції. Відхиляйте сповіщення з t старшим за 5 хвилин. Приклад на Node.js:
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(rawBody, headerValue, secret) {
const parts = Object.fromEntries(
headerValue.split(',').map((p) => p.split('=')),
);
if (!parts.t || !parts.v1) return false;
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const expected = createHmac('sha256', secret)
.update(`${parts.t}.${rawBody}`)
.digest('hex');
return timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(parts.v1, 'hex'));
}
і на PHP:
function qamera_verify($rawBody, $header, $secret) {
parse_str(strtr($header, ',', '&'), $parts);
if (!isset($parts['t']) || !isset($parts['v1'])) return false;
if (abs(time() - (int)$parts['t']) > 300) return false;
$expected = hash_hmac('sha256', $parts['t'] . '.' . $rawBody, $secret);
return hash_equals($expected, $parts['v1']);
}
Після заміни секрета (POST /installations/{id}/rotate-hmac) протягом 48 годин сповіщення мають два сегменти v1= — один для старого, другий для нового секрета. Приймайте будь-який із них. Повний контракт підпису описує протокол вебхука.
3. Відповідайте швидко й обробляйте ідемпотентно
- Відповідайте будь-яким статусом
2xx— найкраще одразу, а обробку виконуйте у фоні. - Обробляйте ідемпотентно (наприклад, за
job.id+event): за повільної відповіді ми можемо повторно надіслати вже доставлене сповіщення. - Зберігайте
(event, job.id, delivered_at)— знадобиться при діагностиці.
4. Повтори та повторне надсилання
Якщо ваш ендпойнт не відповідає 2xx, ми повторюємо до 8 разів зі зростаючим інтервалом (до 1 години). Після 5 поспіль невдалих доставлень ми призупиняємо надсилання на 30 хвилин; після 3 таких циклів інсталяція зупиняється.
Сповіщення, яке не вдалося доставити, ви можете надіслати повторно:
curl -X POST https://qamera.ai/api/v1/plugin/webhooks/00000000-0000-0000-0000-0000000000d1/replay \ -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"
Повертає 202 з ідентифікатором нового доставлення.
Кроки — опитування (альтернатива)
Не хочете утримувати публічний ендпойнт? Опитуйте про стан завдань:
# одне завдання curl https://qamera.ai/api/v1/plugin/jobs/00000000-0000-0000-0000-0000000000a1 \ -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" # усі завершені від вказаного моменту curl "https://qamera.ai/api/v1/plugin/jobs?status=completed&created_after=2026-06-03T00:00:00Z&limit=50" \ -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"
Підказки:
- Опитуйте кожні 15–30 секунд, не частіше — ліміт запитів ключа (за замовчуванням 60/хв) має вмістити й інші виклики.
- Стан усієї сесії сукупно повертає
GET /orders/{id}— для кожного продукту побачитеjobs_total,jobs_completed,jobs_failedі список результатів. - Вебхуки й опитування можна поєднувати: вебхук як основний канал, опитування як страхувальна сітка.
Прострочені адреси для завантаження
Адреси в outputs[].url дійсні щонайменше 7 днів. Після цього отримайте свіжі:
curl -X POST https://qamera.ai/api/v1/plugin/jobs/00000000-0000-0000-0000-0000000000a1/refresh-url \ -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"
Відповідь містить нові outputs[] і expires_at. Утім, найкраще завантажте файли на свій бік одразу після отримання результату — не сприймайте наші адреси як постійний хостинг.
Поширені помилки
| Помилка | Чому виникла | Що зробити |
|---|---|---|
| Вебхуки не надходять | Немає callback_url на інсталяції або ендпойнт не відповідає 2xx | Встановіть callback_url у налаштуваннях інсталяції; перевірте логи свого ендпойнта |
| Перевірка підпису не проходить | Перевіряєте оброблене body замість сирого; неправильний секрет; минуло вікно ротації | Підписуйте точно сирі байти body; після ротації оновіть секрет протягом 48 год |
409 при replay | Оригінальне доставлення не в стані, придатному для повтору | Повторюйте лише невдалі/покинуті доставлення |
409 job_not_completed при refresh-url | Завдання ще триває | Зачекайте на status: "completed" — подробиці |
410 при refresh-url | Файли видалено згідно з політикою зберігання | Завантажуйте файли на свій бік одразу після генерації — подробиці |
Що далі
- Протокол вебхука — повний контракт підпису й надійності.
- Сесії гуртом — вебхуки при великій кількості завдань.
- Повторна сесія — наступний раунд зображень.