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

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/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": "john@example.com" },
    "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/webhookswebhooks:manage

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

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

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

bash
curl -X POST "https://www.getly.store/api/v1/webhooks" \
  -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 (продление по карте не прошло, Stripe повторяет), 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

Вебхуки

Вебхуки позволяют вашему приложению получать уведомления в реальном времени о событиях в магазине. Регистрируйте эндпоинты на /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

{
  "event": "sale.completed",
  "deliveryId": "uuid",
  "data": {
    "orderId": "uuid",
    "productId": "uuid",
    "buyerEmail": "john@example.com",
    "amount": 2999
  },
  "timestamp": "2025-01-15T10: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 для подтверждения получения.