Passer au contenu principal

Landing pages

CRUD pour les landing pages — pages de conversion mono-produit avec sections (carrousels, formulaires de commande, faux visiteurs, comptes à rebours, offres spéciales).

Écrit par Support

Une landing page est une page de conversion focalisée sur un seul produit. Elles sont indépendantes du catalogue boutique — vous pouvez avoir une landing page sans produit en ligne (pour des lancements à venir), ou une liée à un produit pour des pubs payantes.

Les sections (carrousels, faux visiteurs, comptes à rebours, etc.) sont gérées dans le tableau de bord en v1 ; l'API ne fait que CRUD sur l'enregistrement parent. Une mise à jour v1.1 exposera aussi le CRUD des sections.

Limites par plan

Plan

Landing pages (tous statuts — les brouillons comptent)

Free

0 (achat unique : 1000 DZD / à vie chacune)

Pro

3

Unlimited / Enterprise

illimité

Le plafond n'est appliqué que par les flux création / duplication du tableau de bord, en comptant chaque landing page, brouillons inclus. L'API n'applique rien : POST /v1/landing-pages suivi de /publish contourne totalement le plafond, et sur un plan payant les pages en trop s'affichent bien en ligne sur la vitrine. Sur le plan Free, les pages restent invisibles sauf si la page a été achetée (is_purchased).

GET /v1/landing-pages

Liste les landing pages. Pagination par curseur. Mis en cache pendant 30 s — vérifiez l'en-tête de réponse X-Cache: HIT|MISS. GET /v1/landing-pages/{id} n'est pas mis en cache.

Auth : n'importe quelle clé plateforme active de la boutique (landing_pages:read n'est pas appliqué en v1 ; seul landing_pages:write est contrôlé, sur les endpoints d'écriture).

Paramètres de requête

Param

Type

Notes

limit

int 1–200

Défaut 50

cursor

string

Opaque

status

active | draft

Filtre

Un status non reconnu est ignoré : toutes les pages sont renvoyées plutôt qu'un 400.

Réponse 200

{
  "data": {
    "items": [
      {
        "id":            42,
        "title":         "Black T-Shirt — 30% off",
        "slug":          "black-tshirt-30-off",
        "status":        "active",
        "language":      "ar",
        "product_id":    26,
        "views":         1543,
        "is_purchased":  false,
        "created_at":    "2026-03-01 10:00:00",
        "updated_at":    "2026-03-15 14:22:11"
      }
    ],
    "next_cursor": null,
    "has_more": false
  }
}

GET /v1/landing-pages/{id}

Détail avec section_count.

{
  "data": {
    "id":               42,
    "title":            "Black T-Shirt — 30% off",
    "slug":             "black-tshirt-30-off",
    "status":           "active",
    "language":         "ar",
    "product_id":       26,
    "views":            1543,
    "is_purchased":     false,
    "meta_title":       "Black T-Shirt — Cotton 200gsm — 30% off | DZBuild",
    "meta_description": "Limited-time offer on our cotton black t-shirt.",
    "section_count":    7,
    "created_at":       "2026-03-01 10:00:00",
    "updated_at":       "2026-03-15 14:22:11"
  }
}

Référence des champs

Champ

Notes

status

Strictement active ou draft — il n'y a pas d'état archived pour les landing pages.

language

ar, fr ou en.

product_id

Le produit lié, ou null. Une page sans product id ne peut pas tarifer correctement son formulaire de commande.

views

Lecture seule. Compté à chaque consultation de la page publique ; l'API ne peut pas l'écrire et il n'existe aucun moyen de le remettre à zéro.

is_purchased

true une fois la page achetée définitivement (1000 DZD / à vie). Sur le plan Free, c'est ce qui rend la page visible sur la vitrine.

section_count

Endpoint détail uniquement — un comptage en direct des sections de la page, calculé à chaque requête.

meta_title / meta_description

Balises SEO. Voir la note sous création.

POST /v1/landing-pages — créer

Auth : clé plateforme avec landing_pages:write. Nécessite Idempotency-Key.

Corps

Champ

Type

Requis

Notes

title

string 1–255

slug

string

Auto-déduit de title si omis. Un slug que vous fournissez ici est stocké sans normalisation — envoyez-en un propre

status

active | draft

Défaut draft. Toute autre valeur est silencieusement ramenée à draft

language

ar | fr | en

Défaut ar. Toute autre valeur est silencieusement ramenée à ar

product_id

int

Doit appartenir à votre boutique ; la page lie ce produit

meta_title

string ≤ 255

Titre SEO. Omis via l'API, il est stocké et renvoyé comme null (contrairement au formulaire du tableau de bord, qui y recopie title). La page publique affiche quand même title en repli, le titre visible est donc correct dans les deux cas

meta_description

string

Description SEO

Les slugs sont rendus uniques dans votre boutique par ajout de -2, -3, … Une base de slug vide retombe sur landing- suivi de 6 caractères hex.

Erreurs

Code

Cause

bad_request "Body must be valid JSON"

Content-Type incorrect ou JSON malformé

bad_request "title is required (1-255 chars)"

Titre manquant ou trop long

bad_request "product_id N does not belong to this store"

ID cross-boutique

Requête

curl -X POST 'https://api.dzbuild.app/v1/landing-pages' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "title":      "Black T-Shirt — 30% off",
    "language":   "ar",
    "product_id": 26,
    "status":     "draft"
  }'

Renvoie 200 (et non 201) avec la même forme que GET /v1/landing-pages/{id}. La nouvelle landing page n'a aucune section — peuplez-les depuis le dashboard.

PATCH /v1/landing-pages/{id}

Mise à jour partielle.

PATCH valide plus strictement que la création : un status invalide renvoie 400 bad_request (« status must be active or draft ») et un language invalide renvoie 400 (« language must be ar, fr, or en ») au lieu d'être coercé. title doit toujours faire 1 à 255 caractères. Un slug envoyé sur PATCH est normalisé, contrairement à la création.

curl -X PATCH 'https://api.dzbuild.app/v1/landing-pages/42' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "title": "Black T-Shirt — Spring promo" }'

Renommer régénère slug automatiquement uniquement si vous n'avez pas envoyé slug explicitement.

POST /v1/landing-pages/{id}/publish

Raccourci : passer le status à active. Équivaut à PATCH ... { status: "active" }.

curl -X POST 'https://api.dzbuild.app/v1/landing-pages/42/publish' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Idempotency-Key: publish-42-$(date +%s)"

DELETE /v1/landing-pages/{id}

Suppression dure. Les sections de la page sont supprimées avec elle.

curl -X DELETE 'https://api.dzbuild.app/v1/landing-pages/42' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Idempotency-Key: del-42"

Réponse : { "data": { "deleted": true, "id": 42 } }.

Avez-vous trouvé la réponse à votre question ?