URL de base : https://www.getly.store. Tous les prix sont en centimes (ex. : 1999 = 19,99 $).
GET/api/v1/productsread:products
Lister les produits de votre boutique
curl -X GET "https://www.getly.store/api/v1/products?page=1&limit=20" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · 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
Créer un nouveau produit dans votre boutique
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" }]
}'
Réponse · 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
Obtenir les détails d'un produit par ID
curl -X GET "https://www.getly.store/api/v1/products/{id}" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · application/json
{
"success": true,
"data": {
"id": "uuid",
"name": "Premium Icon Pack",
"price": 1999,
"images": [...],
"files": [...],
"reviews": [...]
}
}
PATCH/api/v1/products/:idwrite:products
Mettre à jour un produit existant
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 }'
Réponse · application/json
{
"success": true,
"data": { "id": "uuid", "name": "Updated Name", "price": 3999 }
}
DELETE/api/v1/products/:idwrite:products
Archivez (suppression logique) un produit. Il n'est plus listé publiquement ; les commandes et téléchargements existants continuent de fonctionner.
curl -X DELETE "https://www.getly.store/api/v1/products/{id}" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · application/json
{
"success": true,
"data": { "id": "uuid", "status": "archived" },
"message": "Product archived"
}
POST/api/v1/products/:id/fileswrite:products
Joignez un fichier téléchargeable à un produit. Utilisez multipart pour les petits fichiers, ou la sous-route presign + un PUT direct vers R2 pour les fichiers jusqu'à 2 Go. Vous pouvez aussi passer un tableau files[] à POST /api/v1/products pour les joindre dès la création.
# 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" }'
Réponse · 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
Obtenez une URL présignée pour téléverser l'image d'un produit (max. 10 Mo ; png, jpeg, webp, gif, avif). Obligatoire avant qu'un produit puisse être mis en ligne.
# 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) with the
# returned uploadHeaders. Content-Length MUST equal the fileSize you declared.
# Send Content-Type equal to the declared type (curl --data-binary alone sends
# a form type; Getly corrects it when the image is attached, but send it anyway).
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>"] }'
Réponse · application/json
{
"success": true,
"data": {
"uploadUrl": "https://<bucket>.r2.cloudflarestorage.com/...",
"uploadHeaders": { "Content-Type": "image/png" },
"publicUrl": "https://cdn.getly.store/images/.../abc.png",
"expiresIn": 3600
}
}
GET/api/v1/products/:id/keysread:products
Listez le pool de clés de licence d'un produit : compteurs (disponibles/émises/en attente) et une liste paginée et masquée. La clé en clair n'est jamais renvoyée.
curl -X GET "https://www.getly.store/api/v1/products/{id}/keys?limit=50&offset=0" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · 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
Collez vos propres clés, bons ou URL uniques dans le pool d'un produit, une par élément du tableau. Les doublons et les entrées vides sont signalés, pas ignorés en silence ; les acheteurs qui attendaient reçoivent une clé aussitôt.
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"] }'
Réponse · 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
Retirez une clé non vendue du pool. Une clé émise est une trace de vente et ne peut pas être retirée : 409 key_not_available.
curl -X DELETE "https://www.getly.store/api/v1/products/{id}/keys/{keyId}" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · application/json
{
"success": true,
"data": { "id": "uuid", "removed": true }
}
GET/api/v1/ordersread:orders
Lister les commandes contenant des articles de votre boutique
curl -X GET "https://www.getly.store/api/v1/orders?page=1&limit=20" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · 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
Obtenir les détails d'une commande (uniquement les articles de votre boutique)
curl -X GET "https://www.getly.store/api/v1/orders/{id}" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · application/json
{
"success": true,
"data": {
"id": "uuid",
"status": "completed",
"total": 5999,
"buyer": { "name": "John", "email": "[email protected]" },
"items": [...]
}
}
GET/api/v1/storeread:store
Obtenir les informations de votre boutique
curl -X GET "https://www.getly.store/api/v1/store" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · application/json
{
"success": true,
"data": {
"id": "uuid",
"name": "My Store",
"slug": "my-store",
"description": "...",
"totalSales": 250,
"totalRevenue": 450000,
"badges": [...]
}
}
PATCH/api/v1/storewrite:store
Mettre à jour le nom de la boutique, la description, le site web et socialLinks
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" }'
Réponse · application/json
{
"success": true,
"data": { "id": "uuid", "name": "My Store", "description": "Updated store description" }
}
GET/api/v1/analyticsread:analytics
Obtenez les statistiques de ventes de votre boutique
curl -X GET "https://www.getly.store/api/v1/analytics" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · 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
Listez les endpoints de webhook de votre boutique
curl -X GET "https://www.getly.store/api/v1/webhook-endpoints" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · 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
Enregistrez un nouvel endpoint de webhook
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"]
}'
Réponse · application/json
{
"success": true,
"data": {
"id": "uuid",
"url": "https://example.com/webhooks",
"events": ["sale.completed", "product.updated"],
"secret": "abcdef1234567890..."
}
}
POST/api/v1/postswrite:posts
Créez un article de blog de créateur à partir de Markdown. Mettez crosspostMuhamor à true pour l'afficher aussi dans la communauté Getly Creators sur Muhamor : la copie renvoie vers votre article comme original, et un article réservé aux abonnés n'y apparaît que sous forme d'aperçu.
curl -X POST "https://www.getly.store/api/v1/posts" \
-H "Authorization: Bearer gk_your_api_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7b1f0c2e-post-1" \
-d '{
"title": "How I made my icon pack",
"contentMarkdown": "## The idea\n\nIt started with...",
"status": "published",
"crosspostMuhamor": true
}'
Réponse · application/json
{
"success": true,
"data": {
"id": "uuid",
"title": "How I made my icon pack",
"slug": "how-i-made-my-icon-pack",
"status": "published",
"crosspostMuhamor": true
}
}
GET/api/v1/public/products/{slug}public
Public, sans clé d'API : la fiche d'un produit actif à partir de son slug (nom, prix en centimes avec toute promotion en cours, image de couverture, boutique). 404 pour tout ce qui n'est pas en vente. 60 requêtes par minute par IP.
curl "https://www.getly.store/api/v1/public/products/premium-icon-pack-abc123"
Réponse · application/json
{
"success": true,
"data": {
"slug": "premium-icon-pack-abc123",
"name": "Premium Icon Pack",
"shortDescription": "120 line icons",
"priceCents": 1999,
"currency": "USD",
"avgRating": 4.8,
"reviewCount": 12,
"imageUrl": "https://cdn.getly.store/images/.../cover.webp",
"store": { "name": "Pixel Studio", "slug": "pixel-studio" },
"urls": { "product": "https://www.getly.store/product/premium-icon-pack-abc123" }
}
}
POST/api/v1/billing/planswrite:billing
Créez un plan récurrent pour votre PROPRE produit (Getly Billing). amount en centimes entiers (min. 50), intervalUnit day/week/month/year, intervalCount 1–52. Nécessite une demande Billing approuvée : 403 billing_not_approved d'ici là. GET liste les plans ; GET/PATCH /{id} en lit et en modifie un.
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" }'
Réponse · 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
Générez une page d'abonnement hébergée pour un client, valable 24 heures. customerRef est votre propre identifiant du client et revient dans chaque webhook billing.* sous le nom externalCustomerRef. Le client paie par carte (renouvellement automatique) ou en crypto (une période à la fois).
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" }'
Réponse · 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
La vérification d'état que fait votre backend avant d'accorder l'accès. status : active, past_due (le renouvellement par carte a échoué, le processeur réessaie), canceled, expired (la période payée en crypto est épuisée). Considérez active et past_due comme ayant droit à l'accès jusqu'à currentPeriodEnd. L'endpoint de liste filtre par status, customerRef et planId.
curl "https://www.getly.store/api/v1/billing/subscriptions/uuid" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · 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
Arrête le renouvellement à la fin de la période payée, jamais une coupure immédiate. Vous recevez billing.subscription.canceled à la fin (carte) ou billing.subscription.expired (crypto). 409 subscription_not_cancellable si déjà terminé.
curl -X POST "https://www.getly.store/api/v1/billing/subscriptions/uuid/cancel" \
-H "Authorization: Bearer gk_your_api_key"
Réponse · application/json
{
"success": true,
"data": { "id": "uuid", "status": "active", "cancelAtPeriodEnd": true, "currentPeriodEnd": "2026-10-08T09:14:00.000Z" }
}