Skip to main content
Getly

API

API Documentation

Complete reference for the Getly Developer API v1

Authentication

All API requests must include your API key in the Authorization header using the Bearer token scheme.

HTTP header
Authorization: Bearer gk_your_api_key_here

Available Scopes

API keys are scoped to a specific store and have granular permissions. Create keys at /dashboard/developer/keys.

read:productswrite:productsread:ordersread:storewrite:storeread:analyticswebhooks:manageread:postswrite:postsread:couponswrite:couponsread:licenseswrite:licensescheckout:create

Rate Limits

API requests are rate limited to 100 requests per minute per API key. If you exceed the limit, you will receive a 429 response — wait a short moment and retry.

Plan your integrations to stay within these limits. Batch operations where possible and cache responses on your end.

Error Handling

All API responses follow a consistent format. Errors include a descriptive message.

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

// Error
{ "success": false, "error": "Description of what went wrong" }

HTTP Status Codes

200 Success

201 Created

400 Bad Request (invalid input)

401 Unauthorized (missing/invalid API key)

403 Forbidden (missing scope or not your resource)

404 Not Found

500 Internal Server Error

Endpoints

Base URL: https://www.getly.store. All prices are in cents (e.g. 1999 = $19.99).

GET/api/v1/productsread:products

List products for your store

bash
curl -X GET "https://www.getly.store/api/v1/products?page=1&limit=20" \
  -H "Authorization: Bearer gk_your_api_key"
Response · 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

Create a new product in your store

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" }]
  }'
Response · 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

Get product details by ID

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

Update an existing product

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 }'
Response · application/json
{
  "success": true,
  "data": { "id": "uuid", "name": "Updated Name", "price": 3999 }
}
DELETE/api/v1/products/:idwrite:products

Archive (soft-delete) a product. It stops being publicly listed; existing orders and downloads keep working.

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

Attach a downloadable file to a product. Use multipart for small files, or the presign sub-route + a direct R2 PUT for files up to 2GB. You can also pass a files[] array to POST /api/v1/products to attach at creation time.

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" }'
Response · 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"
  }
}
GET/api/v1/ordersread:orders

List orders containing items from your store

bash
curl -X GET "https://www.getly.store/api/v1/orders?page=1&limit=20" \
  -H "Authorization: Bearer gk_your_api_key"
Response · 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

Get order details (only items from your store)

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

Get your store information

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

Update store name, description, website, socialLinks

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" }'
Response · application/json
{
  "success": true,
  "data": { "id": "uuid", "name": "My Store", "description": "Updated store description" }
}
GET/api/v1/analyticsread:analytics

Get sales analytics for your store

bash
curl -X GET "https://www.getly.store/api/v1/analytics" \
  -H "Authorization: Bearer gk_your_api_key"
Response · 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

List webhook endpoints for your store

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

Register a new webhook endpoint

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"]
  }'
Response · application/json
{
  "success": true,
  "data": {
    "id": "uuid",
    "url": "https://example.com/webhooks",
    "events": ["sale.completed", "product.updated"],
    "secret": "abcdef1234567890..."
  }
}

Webhooks

Webhooks allow your application to receive real-time notifications when events happen in your store. Register endpoints at /dashboard/developer/webhooks or via the API.

Event Types

sale.completed A sale was completed for one of your products

product.created A product was created in your store

product.updated A product in your store was updated

review.created A new review was left on one of your products

download.completed A buyer downloaded one of your products

* Subscribe to all events

Payload Format

Every webhook delivery sends a JSON POST request with the following structure:

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"
}

Signature Verification

Every webhook delivery includes an X-Getly-Signature header. Verify the signature using HMAC-SHA256 with your webhook secret to ensure the request came from Getly.

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');
});

Retry Policy

Failed deliveries (non-2xx response or timeout) are retried automatically with exponential backoff:

Attempt 1: Retry after 1 minute

Attempt 2: Retry after 5 minutes

Attempt 3: Retry after 30 minutes

Attempt 4: Retry after 2 hours

Attempt 5: Give up (delivery marked as failed)

Your endpoint should respond within 10 seconds. Return a 2xx status code to acknowledge receipt.