Перейти к основному содержимому
Getly

Меню команд

Перейти на страницу или искать в каталоге

API

Документация API

Полный справочник по Getly Developer API v1

Аутентификация

Все API-запросы должны включать ваш API-ключ в заголовке Authorization с использованием схемы Bearer токена.

HTTP header
Authorization: Bearer gk_your_api_key_here

Доступные права

API-ключи привязаны к конкретному магазину и имеют гранулярные разрешения. Создавайте ключи на /dashboard/developer/keys.

read:productswrite:productsread:ordersread:storewrite:storeread:analyticswebhooks:manageread:postswrite:postsread:couponswrite:couponsread:licenseswrite:licensescheckout:createread:billingwrite:billing

Лимиты запросов

Запросы к API ограничены до 100 requests per minute на ключ. При превышении лимита вы получите ответ 429 - подождите немного и повторите попытку.

Планируйте интеграции в рамках этих лимитов. По возможности используйте пакетные операции и кешируйте ответы.

Обработка ошибок

Все ответы API следуют единому формату. Ошибки содержат описательное сообщение.

application/json
// Success
{ "success": true, "data": { ... } }

// Error
{
  "success": false,
  "error": "Description of what went wrong",
  "errorDetail": {
    "code": "validation_failed",   // stable, safe to branch on
    "message": "price must be a positive integer in cents",
    "hint": "Fix the field named in `param` and retry the same request.",
    "param": "price",              // omitted when no single field is at fault
    "docsUrl": "https://www.getly.store/developers/docs#errors"
  }
}

HTTP-коды статусов

200 - Успех

201 - Создано

400 - Некорректный запрос (неверные данные)

401 - Не авторизован (отсутствует/неверный API-ключ)

403 - Запрещено (нет прав или не ваш ресурс)

404 - Не найдено

500 - Внутренняя ошибка сервера

Эндпоинты

Базовый URL: https://www.getly.store. Все цены в центах (напр. 1999 = $19.99).

GET/api/v1/productsread:products

Список товаров вашего магазина

bash
curl -X GET "https://www.getly.store/api/v1/products?page=1&limit=20" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "name": "Premium Icon Pack",
      "slug": "premium-icon-pack-abc123",
      "price": 1999,
      "status": "active",
      "category": { "id": "uuid", "name": "Design", "slug": "design" },
      "images": [{ "url": "...", "altText": "..." }]
    }
  ],
  "total": 42,
  "page": 1,
  "limit": 20,
  "hasMore": true
}
POST/api/v1/productswrite:products

Создать новый товар в магазине

bash
curl -X POST "https://www.getly.store/api/v1/products" \
  -H "Authorization: Bearer gk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My New Product",
    "description": "A great digital product",
    "price": 29.99,
    "categoryId": "uuid",
    "status": "active",
    "tags": ["design", "icons"],
    "images": [{ "url": "https://cdn.getly.store/...png", "altText": "cover" }],
    "files": [{ "fileUrl": "https://cdn.getly.store/files/.../abc.zip", "fileName": "pack.zip", "fileSize": 10485760, "fileType": "application/zip" }]
  }'
Ответ · application/json
{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "My New Product",
    "slug": "my-new-product-abc123",
    "price": 2999,
    "status": "active",
    "createdAt": "2025-01-15T10:30:00Z"
  }
}
GET/api/v1/products/:idread:products

Получить информацию о товаре по ID

bash
curl -X GET "https://www.getly.store/api/v1/products/{id}" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Premium Icon Pack",
    "price": 1999,
    "images": [...],
    "files": [...],
    "reviews": [...]
  }
}
PATCH/api/v1/products/:idwrite:products

Обновить существующий товар

bash
curl -X PATCH "https://www.getly.store/api/v1/products/{id}" \
  -H "Authorization: Bearer gk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Updated Name", "price": 39.99 }'
Ответ · application/json
{
  "success": true,
  "data": { "id": "uuid", "name": "Updated Name", "price": 3999 }
}
DELETE/api/v1/products/:idwrite:products

Архивировать (мягкое удаление) товар. Он перестаёт показываться публично; существующие заказы и загрузки продолжают работать.

bash
curl -X DELETE "https://www.getly.store/api/v1/products/{id}" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": { "id": "uuid", "status": "archived" },
  "message": "Product archived"
}
POST/api/v1/products/:id/fileswrite:products

Прикрепить загружаемый файл к товару. Для небольших файлов используйте multipart, для файлов до 2 ГБ - подмаршрут presign и прямой PUT в R2. Также можно передать массив files[] в POST /api/v1/products, чтобы прикрепить файл при создании.

bash
# Direct upload (multipart) - best for files under ~4MB:
curl -X POST "https://www.getly.store/api/v1/products/{id}/files" \
  -H "Authorization: Bearer gk_your_api_key" \
  -F "file=@/path/to/your-file.zip"

# Large files (up to 2GB) - 3 steps:
# 1) get a presigned upload URL
curl -X POST "https://www.getly.store/api/v1/products/{id}/files/presign" \
  -H "Authorization: Bearer gk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "fileName": "pack.zip", "fileSize": 524288000, "fileType": "application/zip" }'
# 2) PUT the bytes straight to R2 (use the returned uploadUrl)
curl -X PUT "<uploadUrl>" --data-binary "@/path/to/pack.zip" \
  -H "Content-Length: 524288000"
# 3) attach the uploaded object (use the returned fileUrl)
curl -X POST "https://www.getly.store/api/v1/products/{id}/files" \
  -H "Authorization: Bearer gk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "fileUrl": "<fileUrl>", "fileName": "pack.zip", "fileSize": 524288000, "fileType": "application/zip" }'
Ответ · application/json
{
  "success": true,
  "data": {
    "id": "uuid",
    "fileName": "pack.zip",
    "fileUrl": "https://cdn.getly.store/files/.../abc.zip",
    "fileSize": 524288000,
    "fileType": "application/zip",
    "version": "1.0",
    "isLatest": true,
    "createdAt": "2026-06-02T10:30:00Z"
  }
}
POST/api/v1/uploads/images/presignwrite:products

Получить подписанную ссылку для загрузки картинки товара (до 10 МБ; png, jpeg, webp, gif, avif). Без картинки товар не может стать активным.

bash
# Images are uploaded in 3 steps - there is no direct multipart route.
# 1) ask for a presigned URL (max 10MB; png, jpeg, webp, gif or avif)
curl -X POST "https://www.getly.store/api/v1/uploads/images/presign" \
  -H "Authorization: Bearer gk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "fileName": "cover.png", "fileSize": 184320, "contentType": "image/png" }'

# 2) PUT the raw bytes to the returned uploadUrl (expires in 1h).
#    Content-Length MUST equal the fileSize you declared.
curl -X PUT "<uploadUrl>" --data-binary "@/path/to/cover.png" \
  -H "Content-Type: image/png" -H "Content-Length: 184320"

# 3) reference the returned publicUrl when you create or update the product.
#    An image is REQUIRED before a product can go live.
curl -X PATCH "https://www.getly.store/api/v1/products/{id}" \
  -H "Authorization: Bearer gk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "images": ["<publicUrl>"] }'
Ответ · application/json
{
  "success": true,
  "data": {
    "uploadUrl": "https://<bucket>.r2.cloudflarestorage.com/...",
    "publicUrl": "https://cdn.getly.store/images/.../abc.png",
    "expiresIn": 3600
  }
}
GET/api/v1/products/:id/keysread:products

Список собственного пула лицензионных ключей товара: счётчики (доступно/выдано/в ожидании) и маскированный постраничный список. Ключ в открытом виде никогда не возвращается.

bash
curl -X GET "https://www.getly.store/api/v1/products/{id}/keys?limit=50&offset=0" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": {
    "keyPoolEnabled": true,
    "keyPoolLowThreshold": 5,
    "counts": { "available": 12, "issued": 40, "waiting": 0 },
    "keys": [
      { "id": "uuid", "masked": "ABCD…WXYZ", "status": "available", "issuedAt": null, "orderItemId": null, "refunded": false }
    ],
    "limit": 50,
    "offset": 0,
    "total": 52
  }
}
POST/api/v1/products/:id/keyswrite:products

Добавить свои ключи, коды купонов или уникальные ссылки в пул товара - по одному элементу массива. Дубликаты и пустые строки сообщаются, а не отбрасываются молча; покупатели, ожидавшие ключ, получают его сразу.

bash
curl -X POST "https://www.getly.store/api/v1/products/{id}/keys" \
  -H "Authorization: Bearer gk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "keys": ["ABCD-1234-EFGH-5678", "IJKL-9012-MNOP-3456"] }'
Ответ · application/json
{
  "success": true,
  "data": {
    "added": 2,
    "duplicates": 0,
    "duplicatesInInput": 0,
    "tooLong": 0,
    "blank": 0,
    "filled": 1
  }
}
DELETE/api/v1/products/:id/keys/:keyIdwrite:products

Удалить непроданный ключ из пула. Выданный ключ - это запись о продаже, его удалить нельзя - 409 key_not_available.

bash
curl -X DELETE "https://www.getly.store/api/v1/products/{id}/keys/{keyId}" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": { "id": "uuid", "removed": true }
}
GET/api/v1/ordersread:orders

Список заказов с товарами из вашего магазина

bash
curl -X GET "https://www.getly.store/api/v1/orders?page=1&limit=20" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "orderId": "uuid",
      "price": 2999,
      "order": { "status": "completed", "buyer": { "name": "John" } },
      "product": { "name": "Premium Pack" }
    }
  ],
  "total": 156,
  "page": 1
}
GET/api/v1/orders/:idread:orders

Детали заказа (только ваши товары)

bash
curl -X GET "https://www.getly.store/api/v1/orders/{id}" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": {
    "id": "uuid",
    "status": "completed",
    "total": 5999,
    "buyer": { "name": "John", "email": "[email protected]" },
    "items": [...]
  }
}
GET/api/v1/storeread:store

Информация о вашем магазине

bash
curl -X GET "https://www.getly.store/api/v1/store" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "My Store",
    "slug": "my-store",
    "description": "...",
    "totalSales": 250,
    "totalRevenue": 450000,
    "badges": [...]
  }
}
PATCH/api/v1/storewrite:store

Обновить название, описание, сайт, соцсети магазина

bash
curl -X PATCH "https://www.getly.store/api/v1/store" \
  -H "Authorization: Bearer gk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "description": "Updated store description" }'
Ответ · application/json
{
  "success": true,
  "data": { "id": "uuid", "name": "My Store", "description": "Updated store description" }
}
GET/api/v1/analyticsread:analytics

Аналитика продаж вашего магазина

bash
curl -X GET "https://www.getly.store/api/v1/analytics" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": {
    "totalSales": 250,
    "totalRevenue": 450000,
    "monthlySales": 42,
    "monthlyRevenue": 75000,
    "averageOrderValue": 1800,
    "productCount": 15,
    "totalDownloads": 1200,
    "salesByMonth": [
      { "month": "2025-01", "sales": 38, "revenue": 68000 }
    ]
  }
}
GET/api/v1/webhook-endpointswebhooks:manage

Список вебхуков вашего магазина

bash
curl -X GET "https://www.getly.store/api/v1/webhook-endpoints" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": {
    "items": [
      {
        "id": "uuid",
        "url": "https://example.com/webhooks",
        "events": ["sale.completed"],
        "isActive": true
      }
    ],
    "nextCursor": null
  }
}
POST/api/v1/webhook-endpointswebhooks:manage

Зарегистрировать новый вебхук

bash
curl -X POST "https://www.getly.store/api/v1/webhook-endpoints" \
  -H "Authorization: Bearer gk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks",
    "events": ["sale.completed", "product.updated"]
  }'
Ответ · application/json
{
  "success": true,
  "data": {
    "id": "uuid",
    "url": "https://example.com/webhooks",
    "events": ["sale.completed", "product.updated"],
    "secret": "abcdef1234567890..."
  }
}
POST/api/v1/billing/planswrite:billing

Создать регулярный план для ВАШЕГО продукта (Getly Billing). amount - целые центы (от 50), intervalUnit day/week/month/year, intervalCount 1–52. Нужна одобренная заявка на Биллинг - до этого 403 billing_not_approved. GET перечисляет планы; GET/PATCH /{id} читает и правит один.

bash
curl -X POST "https://www.getly.store/api/v1/billing/plans" \
  -H "Authorization: Bearer gk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Pro", "amount": 1900, "intervalUnit": "month", "externalId": "pro-monthly" }'
Ответ · application/json
{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Pro",
    "amount": 1900,
    "currency": "usd",
    "interval": { "unit": "month", "count": 1 },
    "externalId": "pro-monthly",
    "isActive": true
  }
}
POST/api/v1/billing/checkoutwrite:billing

Создать страницу подписки у нас для одного клиента, действует 24 часа. customerRef - ваш ID клиента, возвращается на каждом вебхуке billing.* как externalCustomerRef. Клиент платит картой (продлевается сама) или криптой (один период за раз).

bash
curl -X POST "https://www.getly.store/api/v1/billing/checkout" \
  -H "Authorization: Bearer gk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "planId": "uuid", "customerRef": "user_8841",
        "successUrl": "https://your-app.com/welcome",
        "cancelUrl": "https://your-app.com/pricing" }'
Ответ · application/json
{
  "success": true,
  "data": {
    "url": "https://www.getly.store/billing/subscribe/uuid?t=…",
    "expiresAt": "2026-09-09T09:00:00.000Z"
  }
}
GET/api/v1/billing/subscriptions/{id}read:billing

Проверка статуса, которую ваш бэкенд делает перед выдачей доступа. status: active, past_due (продление по карте не прошло, процессинг повторяет), canceled, expired (крипто-период истёк). Считайте active и past_due оплаченными до currentPeriodEnd. Список фильтруется по status, customerRef и planId.

bash
curl "https://www.getly.store/api/v1/billing/subscriptions/uuid" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": {
    "id": "uuid",
    "customerRef": "user_8841",
    "status": "active",
    "paymentMethod": "stripe",
    "currentPeriodEnd": "2026-10-08T09:14:00.000Z",
    "cancelAtPeriodEnd": false,
    "plan": { "name": "Pro", "amount": 1900, "interval": { "unit": "month", "count": 1 } }
  }
}
POST/api/v1/billing/subscriptions/{id}/cancelwrite:billing

Остановить продление в конце оплаченного периода - никогда не мгновенный обрыв. Вы получите billing.subscription.canceled, когда он закончится (карта), или billing.subscription.expired (крипта). 409 subscription_not_cancellable, если уже закончилась.

bash
curl -X POST "https://www.getly.store/api/v1/billing/subscriptions/uuid/cancel" \
  -H "Authorization: Bearer gk_your_api_key"
Ответ · application/json
{
  "success": true,
  "data": { "id": "uuid", "status": "active", "cancelAtPeriodEnd": true, "currentPeriodEnd": "2026-10-08T09:14:00.000Z" }
}

Getly Billing

Регулярные планы для продукта, который вы ведёте сами - SaaS, сообщество, инструмент. Планы живут в API, страница подписки - на getly.store, а ваш бэкенд выдаёт доступ по пяти вебхукам, каждый из которых несёт ваш ID клиента.

Доступ по заявке: укажите сайт и что продаёте на /dashboard/billing. До одобрения записи отвечают 403 billing_not_approved, чтение работает.

  • billing.subscription.created
  • billing.subscription.renewed
  • billing.payment_failed
  • billing.subscription.canceled
  • billing.subscription.expired
Как работает Getly Billing

Доставка собственных лицензионных ключей

Товар может выдавать собственные заранее подготовленные ключи продавца - регистрационные ключи, коды купонов или уникальные ссылки - вместо ключа, сгенерированного Getly. Getly выдаёт следующий ключ на каждую продажу, в порядке добавления (кто раньше вставлен, тот раньше продан), и никогда не блокирует продажу при пустом пуле: покупателю сообщают, что ключ придёт на почту, и он получает его сразу, как только продавец добавит ещё.

  • Панель управления: редактирование товара → шаг «Цена» → «Выдавать мои лицензионные ключи» (пулу нужен id товара, поэтому при создании он недоступен). По одному ключу на строку, до 5,000 за раз; исключает Getly-ключи для того же товара.
  • API: GET/POST /api/v1/products/{id}/keys - список и добавление ключей; DELETE /api/v1/products/{id}/keys/{keyId} - удаление непроданного ключа. keyPoolEnabled и keyPoolLowThreshold задаются на самом товаре, через POST/PATCH /api/v1/products.

Хотите выдавать ключи со своего сервера? Теперь каждый элемент sale.completed несёт licenseKey - уже выданный для этой позиции ключ (из пула или сгенерированный Getly), либо null, пока ключ ещё не выдан - рядом с buyerEmail, так что вы можете переслать его или отправить свой.

Вебхуки

Вебхуки позволяют вашему приложению получать уведомления в реальном времени о событиях в магазине. Регистрируйте эндпоинты на /dashboard/developer/webhooks или через API.

Типы событий

sale.completed - Завершена продажа одного из ваших товаров. Содержит почту покупателя, чтобы вы могли отправить свой лицензионный ключ.

product.created - Товар создан в вашем магазине

product.updated - Товар в вашем магазине обновлён

review.created - Оставлен новый отзыв на ваш товар

download.completed - Покупатель скачал один из ваших товаров

refund.created - Покупатель запросил возврат (решение придёт позже как order.refunded)

order.refunded - По одному из ваших заказов проведён возврат

dispute.created - Покупатель открыл спор

dispute.resolved - Спор закрыт

checkout_link.completed - Ссылка на оплату оплачена

license.activated - Лицензионный ключ активирован

access.expiring - Доступ на срок истекает через 7 дней

access.expired - Доступ на срок истёк

billing.subscription.created - Getly Billing: клиент подписался на один из ваших планов

billing.subscription.renewed - Getly Billing: подписка продлена и оплачена

billing.payment_failed - Getly Billing: платёж за продление не прошёл

billing.subscription.canceled - Getly Billing: подписка отменена

billing.subscription.expired - Getly Billing: подписка, оплаченная криптой, истекла без оплаты

* - Подписка на все события

Формат данных

Каждая доставка вебхука отправляет JSON POST-запрос со следующей структурой:

POST · application/json
POST https://your-endpoint.com/webhooks
Content-Type: application/json
X-Getly-Signature: sha256=<hmac_hex>
X-Getly-Event: sale.completed

{
  "deliveryId": "uuid",
  "event": "sale.completed",
  "data": {
    "orderId": "uuid",
    "buyerId": "uuid",
    "buyerEmail": "[email protected]",
    "items": [
      {
        "orderItemId": "uuid",
        "productId": "uuid",
        "price": 2999,
        "sellerAmount": 2399,
        "isGift": false,
        "licenseKey": null
      }
    ],
    "total": 2999
  },
  "timestamp": "2026-09-23T10:30:00.000Z"
}

Проверка подписи

Каждая доставка вебхука включает заголовок X-Getly-Signature. Проверяйте подпись с помощью HMAC-SHA256 и вашего секрета вебхука.

node.js
const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = 'sha256=' +
    crypto
      .createHmac('sha256', secret)
      .update(body)
      .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your webhook handler
app.post('/webhooks', (req, res) => {
  const signature = req.headers['x-getly-signature'];
  const isValid = verifyWebhook(
    JSON.stringify(req.body),
    signature,
    process.env.GETLY_WEBHOOK_SECRET
  );

  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }

  const { event, data } = req.body;
  // Handle the event...

  res.status(200).send('OK');
});

Политика повторных попыток

Неудачные доставки (не-2xx ответ или таймаут) автоматически повторяются с экспоненциальной задержкой:

Попытка 1: Повтор через 1 минуту

Попытка 2: Повтор через 5 минут

Попытка 3: Повтор через 30 минут

Попытка 4: Повтор через 2 часа

Попытка 5: Отказ (доставка помечена как неудачная)

Ваш эндпоинт должен ответить в течение 10 секунд. Верните код статуса 2xx для подтверждения получения.