NouveautésNouveau

Une seule API pour tous les moteurs de réponse IA

API
Une requête POST /v1/async/task, la tâche en file qu’elle renvoie et la tâche terminée livrée par webhook

Envoyez un prompt au moteur IA de votre choix en une seule requête et recevez la réponse en JSON structuré, par webhook ou par interrogation.

Ce que vous obtenez

  • Un seul endpoint, POST /v1/async/task, pour tous les moteurs. Choisissez le moteur avec taskType et le marché avec country.
  • La même enveloppe pour tous les moteurs : l’id, le status et les horodatages de la tâche entourent une response propre à chaque moteur.
  • Des résultats livrés comme vous le souhaitez : un webhook vers votre serveur dès la fin de la tâche, ou GET /v1/async/task/{id} quand vous êtes prêt.
  • Des relances sûres avec idempotencyKey : renvoyer la même clé retourne la tâche déjà créée.

Fonctionnement

Les moteurs IA mettent de quelques secondes à quelques minutes à répondre, chaque requête devient donc une tâche durable. Une tâche passe de QUEUED à PROCESSING et se termine en COMPLETED avec la réponse ou en FAILED avec la raison. En cas d’erreur temporaire du moteur, la tâche retourne dans la file pour une nouvelle tentative : les incidents brefs sont relancés avant de vous parvenir.

Ajoutez webhook.url et nous envoyons la tâche terminée à votre serveur, avec jusqu’à cinq tentatives sur environ 30 minutes. Les tâches terminées restent aussi disponibles en interrogation pendant 24 heures : webhook et interrogation réunis couvrent chaque résultat.

Cas d’usage

  • Vérifiez la visibilité de votre marque depuis votre propre backend, au rythme de votre choix.
  • Envoyez un même prompt à plusieurs moteurs et comparez les réponses côte à côte.
  • Simplifiez les traitements longs : soumettez, passez à la suite et laissez le webhook rapporter le résultat.

Envoyer la requête

Envoyez la requête avec votre clé API dans l’en-tête Authorization.

curl -X POST https://api.querying.ai/v1/async/task \
  -H "Authorization: Bearer $QUERYING_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "taskType": "CHATGPT",
    "payload": {
      "prompt": "Best coffee shops near me for working on a laptop",
      "country": "US"
    },
    "webhook": { "url": "https://your-server.example.com/hooks/querying" },
    "idempotencyKey": "laptop-cafes-us-0001"
  }'

Champs de la requête

taskTypestringObligatoire
Le moteur à interroger, par exemple CHATGPT ou GOOGLE.
payloadobjectObligatoire
L’entrée du moteur : prompt ou query, plus country et les options du moteur.
webhook.urlstring
Une adresse HTTPS de votre serveur. La tâche terminée y est envoyée dès qu’elle se termine.
idempotencyKeystring
Votre identifiant pour la requête. Chaque clé crée une seule tâche par compte : un envoi répété reste une seule tâche.

Réponse

L’appel répond aussitôt avec la tâche en QUEUED. credits reste à 0 jusqu’à la fin de la tâche, et idempotencyKey revient tel que vous l’avez envoyé.

JSON
{
  "success": true,
  "task": {
    "id": "…",
    "taskType": "CHATGPT",
    "status": "QUEUED",
    "priority": 1,
    "createdAt": "…",
    "idempotencyKey": "laptop-cafes-us-0001"
  },
  "credits": { "creditsToCharge": 0, "creditsCharged": 0 }
}

Recevoir le résultat

Lisez la tâche avec GET /v1/async/task/{id} toutes les quelques secondes jusqu’à ce que status vaille COMPLETED ou FAILED. Les résultats restent disponibles 24 heures après la fin de la tâche.

curl https://api.querying.ai/v1/async/task/$TASK_ID \
  -H "Authorization: Bearer $QUERYING_API_KEY"

Une tâche terminée porte les credits débités et la response du moteur. Celle-ci est réelle, raccourcie pour la lecture.

JSON
{
  "success": true,
  "task": {
    "id": "e5aba119-a26e-4f82-a965-35c9234a428b",
    "taskType": "CHATGPT",
    "status": "COMPLETED",
    "createdAt": "2026-10-02T15:41:03.858Z"
  },
  "credits": { "creditsToCharge": 2, "creditsCharged": 2 },
  "response": {
    "text": "Here are several **nearby cafés that look particularly suitable for laptop work**, based on current local listings and work-friendly details:\n…",
    "sources": [
      {
        "position": 1,
        "url": "https://awifiplace.com/cities/new-york",
        "label": "Best Coffee Shops to Work in New York (2026) | 103 Cafes with WiFi"
      }
    ],
    "searchQueries": [
      "best coffee shops for laptop work near me wifi outlets"
    ]
  }
}
task.statusstring
QUEUED, PROCESSING, puis COMPLETED avec la réponse ou FAILED avec error.
credits.creditsChargedinteger
Crédits facturés pour la tâche terminée. Une tâche en échec facture 0.

Webhooks

Avec webhook.url, la tâche terminée arrive sur votre serveur en POST, avec les mêmes task, credits et response que l’interrogation. Une tâche en échec arrive de la même façon, avec response.error et 0 crédit débité. Trois en-têtes signent chaque livraison :

querying-webhook-idstring
L’ID de la tâche. Chaque livraison arrive au moins une fois : servez-vous-en pour écarter les doublons.
querying-webhook-timestampstring
Secondes Unix au moment de la signature. Acceptez les livraisons signées dans les 5 dernières minutes.
querying-webhook-signaturestring
v1, suivi du HMAC-SHA256 en base64 de {id}.{timestamp}.{body}, avec pour clé l’empreinte SHA-256 de votre clé API.

Vérifiez la signature sur le corps brut, avant de l’analyser, et acceptez la livraison quand elle correspond :

import base64
import hashlib
import hmac
import os
import time


def verify_webhook(headers, body: bytes) -> bool:
    """body is the raw request body, before json.loads."""
    task_id = headers["querying-webhook-id"]
    timestamp = headers["querying-webhook-timestamp"]
    key = hashlib.sha256(os.environ["QUERYING_API_KEY"].encode()).digest()
    signed = f"{task_id}.{timestamp}.".encode() + body
    digest = hmac.new(key, signed, hashlib.sha256).digest()
    expected = "v1," + base64.b64encode(digest).decode()
    given = headers.get("querying-webhook-signature", "")
    fresh = abs(time.time() - int(timestamp)) <= 300
    return fresh and hmac.compare_digest(expected, given)

Répondez avec un statut 2xx en moins de 30 secondes. Après toute autre réponse, ou au-delà de 30 secondes, la livraison repart après 2, 4, 8 et 16 minutes, soit cinq tentatives au total, toutes avec le même querying-webhook-id.

Erreurs

Une requête refusée répond aussitôt avec success à false et un error contenant code, message et, pour une erreur de champ, details. Elle reste hors de la file et coûte 0 crédit.

VALIDATION_ERRORHTTP 400
Un champ manque ou sort des valeurs admises. details indique le champ.
MISSING_API_KEYHTTP 401
L’en-tête Authorization manque, ou sa clé est inconnue, expirée ou révoquée.
INSUFFICIENT_CREDITSHTTP 402
Le solde est inférieur au prix de la tâche. Ajoutez des crédits ou changez de plan, puis renvoyez-la.
KEY_SCOPE_DENIEDHTTP 403
Le moteur est hors des Moteurs autorisés de la clé. Utilisez une autre clé ou ajoutez le moteur dans Gérer la clé.
RESOURCE_ALREADY_EXISTSHTTP 409
Une tâche avec cet idempotencyKey existe déjà sur votre compte : l’envoi reste une seule tâche. Dans un lot, l’élément compte comme réussi.
PAYLOAD_TOO_LARGEHTTP 413
Le corps dépasse 1 Mio, ou 8 Mio pour un lot.
REGION_UNSUPPORTEDHTTP 422
country est hors de la liste des pays du moteur. Un renvoi donne le même résultat, d’où details.retryable à false.
PLAN_CONCURRENCY_LIMITHTTP 429
Vos tâches en file et en cours ont atteint la limite du plan : 2 avec l’offre gratuite, 10 avec Basic, 25 avec Pro, 50 avec Scale et 100 avec Max. Renvoyez après Retry-After secondes.
KEY_DAILY_CREDIT_LIMITHTTP 429
La clé a épuisé sa Limite quotidienne de crédits. Retry-After court jusqu’au prochain minuit UTC.
QUEUE_BACKPRESSUREHTTP 429
La file du moteur est pleine pour le moment. Renvoyez après Retry-After secondes.

Tarif

Chaque moteur a son propre prix en crédits, et une tâche est facturée lorsqu’elle se termine. Une tâche en échec libère les crédits qu’elle avait réservés.

Autres nouveautés

Recevez les nouveautés

Recevez les mises à jour par e-mail.

Flux RSS