Menu

Démarrer avec Wamia Connect

Wamia Connect, c’est un point d’accès GraphQL et des webhooks signés. Une boutique publie ses produits, garde prix et stocks synchronisés, reçoit les commandes Wamia et les expédie — depuis sa propre plateforme ou une intégration sur mesure. Chaque produit passe par le pipeline d’approbation Wamia, exactement comme s’il avait été saisi à la main.

1. Obtenir une clé

La boutique crée une clé personnalisée dans Wamia Shop, Paramètres › API, en choisissant ses portées. La clé n’est affichée qu’une fois ; stockez-la chiffrée. Les connecteurs ne demandent jamais de clé : ils passent par le flux Connect (type OAuth avec PKCE) ou par un code d’appairage à huit caractères et reçoivent une clé liée à la boutique.

Les clés expirent après 365 jours. Faites tourner avant l’échéance avec apiRotateKey ; l’ancienne clé fonctionne encore 24 heures.

2. Choisir le point d’accès

La production répond sur https://api.wamia.tn/connect/graphql, le bac à sable sur https://api-dev.wamia.tn/connect/graphql. Même schéma des deux côtés ; le bac à sable ajoute createSandboxSeller pour ouvrir une boutique de test sans parler à personne.

3. Envoyer les en-têtes attendus

Authentification par Authorization: Bearer wamia_… ou x-api-key. Un connecteur s’identifie par User-Agent: WamiaConnect/<app> <semver> (<détails plateforme>) : l’API y lit la version, refuse un connecteur sous la version minimale avec CONNECTOR_UPGRADE_REQUIRED, et apiConnectorLatest la compare à la dernière version publiée. Une intégration sur mesure envoie le user agent de son choix. Les mutations portent Wamia-Idempotency-Key ; même clé et même contenu renvoient la première réponse, un contenu différent renvoie IDEMPOTENCY_CONFLICT.

Point d’accès

NomURL
Productionhttps://api.wamia.tn/connect/graphql
Bac à sablehttps://api-dev.wamia.tn/connect/graphql

Votre premier appel

Liste les cinq annonces mises à jour le plus récemment pour la boutique de la clé. state indique où en est chacune dans le pipeline d’approbation et buyBox si l’offre gagne actuellement.

curl
curl -sS https://api.wamia.tn/connect/graphql \
  -H 'content-type: application/json' \
  -H 'x-api-key: wamia_…' \
  -H 'user-agent: my-integration/1.0.0 (+https://shop.example.tn)' \
  -H 'wamia-idempotency-key: 6f0e1a2b-…' \
  --data '{"query":"query FirstCall { apiMyListings(limit: 5) { items { sku state priceMillimes availableQty buyBox updatedAt } nextCursor } }"}'
GraphQL
query FirstCall {
  apiMyListings(limit: 5) {
    items { sku state priceMillimes availableQty buyBox updatedAt }
    nextCursor
  }
}

En-têtes de requête

En-têteValeur
AuthorizationBearer wamia_… (ou x-api-key: wamia_…)
User-AgentWamiaConnect/<app> <semver> (<détails plateforme>) — connecteurs ; libre pour une intégration sur mesure
Wamia-Idempotency-KeyUUID ou chaîne de 8 à 128 caractères, mutations seulement
Wamia-Dry-Runtrue — valide et rapporte, n’écrit rien
Content-Typeapplication/json

Erreurs

Sur /connect/graphql, chaque refus est une erreur GraphQL (HTTP 200) avec extensions.code et, quand c’est utile, des détails lisibles par la machine à côté (extensions.retryAfterSeconds, extensions.fields, extensions.pendingBatchId, …) ; la colonne HTTP est la réponse des points REST (/connect/token, /connect/pair, /connect/revoke). Les arguments refusés par le validateur de schéma reviennent en BAD_USER_INPUT. Traitez RATE_LIMITED et BATCH_HELD comme un flux normal, pas comme des pannes.

CodeHTTPSignification
UNAUTHENTICATED401Clé absente ou inconnue.
KEY_EXPIRED401Après expires_at ; faites tourner ou reconnectez.
CONNECTION_REVOKED401La boutique a déconnecté l’application.
CONNECTOR_UPGRADE_REQUIRED426Version du plugin sous le minimum ; extensions.minSupportedVersion précise laquelle.
CONNECTOR_SUSPENDED403Wamia a suspendu ce connecteur (coupe-circuit).
FORBIDDEN_SCOPE403La clé n’a pas la portée exigée par l’opération (voir Portées et limites).
TENANT_MISMATCH403La ressource appartient à une autre boutique.
RATE_LIMITED429Seau vide ; attendez extensions.retryAfterSeconds.
IDEMPOTENCY_CONFLICT409Même clé, contenu différent.
BATCH_HELD409Un coupe-circuit a retenu le lot (extensions.pendingBatchId) ; la boutique le confirme ou le rejette.
BATCH_TOO_LARGE422Plus d’éléments que la limite en lot (extensions.limit).
VALIDATION_FAILED422Problèmes par champ dans extensions.fields[] { field, message }.
MEDIA_FETCH_REFUSED422URL d’image non récupérable (réseau privé, taille, type).
NOT_FOUND404SKU, commande ou point d’accès inconnu.

Les limites dans chaque réponse

Chaque réponse porte extensions.rateLimit { kind, limit, remaining } pour le seau consommé, repris dans les en-têtes X-RateLimit-Limit et X-RateLimit-Remaining ; un 429 ajoute Retry-After. Les erreurs portent extensions.requestId à citer au support. Ralentissez quand remaining approche de zéro au lieu d’attendre le 429.

response
{
  "data": { "apiMyListings": { "items": [ … ], "nextCursor": null } },
  "extensions": {
    "rateLimit": { "kind": "read", "limit": 600, "remaining": 599 }
  }
}

Et ensuite