spicyapiDocumentation
Développer avec l’API
Contenu principal

Devis et compatibilité des protocoles

Connaître le prix exact d’une requête avant de payer, la soumettre à ce prix, reprendre la main après une réponse perdue et savoir comment les API compatibles pour le texte et la vidéo sont facturées.

Obtenir le devis d’une requête précise

Un devis vous indique le prix d’une requête précise avant que vous ne payiez. Il est gratuit, ne crée aucune tâche et ne réserve aucun fonds. Vous soumettez ensuite la même requête en y joignant le devis : elle n’est acceptée qu’au prix qui vous a été affiché.

Les commandes ci-dessous sont prévues pour un terminal macOS ou Linux, avec SPICY_API_KEY défini comme dans le Démarrage rapide. MODEL_ID_FROM_CATALOG est un emplacement réservé : remplacez-le par une valeur model tirée de votre catalogue en direct (GET /api/v1/models), et prenez chaque champ de input dans le schéma de ce modèle.

Enregistrer la requête que vous comptez envoyer

Créez un fichier nommé request.json qui contient exactement le model, l’input et le callBackUrl facultatif que vous allez soumettre :

request.json
{
  "model": "MODEL_ID_FROM_CATALOG",
  "input": { "prompt": "A cinematic night portrait" }
}

Demander le prix

curl https://api.spicyapi.ai/api/v1/jobs/quote \
  -H "Authorization: Bearer $SPICY_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @request.json
{
  "code": 200,
  "msg": "success",
  "data": {
    "quoteId": "QUOTE_ID_FROM_RESPONSE",
    "model": "MODEL_ID_FROM_CATALOG",
    "estimatedCost": "0.008",
    "maxCharge": "0.008",
    "currency": "USD",
    "quantity": "1",
    "unit": "per_image",
    "expiresAt": "2026-09-17T10:05:00Z"
  },
  "request_id": "req_01k3m8x9q2z4v7n5p6r8s0t1w2"
}

Les montants sont des chaînes décimales en dollars américains. maxCharge est le montant maximal que cette requête peut coûter ; aujourd’hui, il est toujours égal à estimatedCost. quantity et unit indiquent ce qui est compté, par exemple des secondes de vidéo. Montrez le montant et expiresAt à la personne qui valide la dépense.

Un devis effectue les mêmes vérifications qu’une vraie soumission, il peut donc déjà échouer : 400 (l’entrée ne correspond pas au schéma du modèle), 40201 (solde insuffisant), 40202 (un plafond de dépense de la clé ou le quota de la plateforme) ou 403 (cette clé n’a pas le droit d’utiliser ce modèle).

Soumettre la même requête avec le devis joint

Dans les cinq minutes, envoyez la requête inchangée à createTask en ajoutant deux champs : quoteId, tiré du devis, et expectedCost, égal à l’estimatedCost du devis. Cette étape coûte de l’argent.

submit.json
{
  "model": "MODEL_ID_FROM_CATALOG",
  "input": { "prompt": "A cinematic night portrait" },
  "quoteId": "QUOTE_ID_FROM_RESPONSE",
  "expectedCost": "0.008"
}
SPICY_IDEMPOTENCY_KEY="$(uuidgen)"   # une fois par nouvelle tâche ; ne la réutilisez que pour renvoyer cette même requête

curl https://api.spicyapi.ai/api/v1/jobs/createTask \
  -H "Authorization: Bearer $SPICY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $SPICY_IDEMPOTENCY_KEY" \
  --data-binary @submit.json

La réponse est la réponse de tâche 202 Accepted habituelle, décrite dans le Démarrage rapide. Le devis ne remplace pas l’Idempotency-Key : envoyez les deux.

Le devis est lié àIl cesse de fonctionner quand
Votre compte et la clé API qui l’a demandéVous soumettez avec une autre clé
Les model, input et callBackUrl exactsL’un d’eux change, ne serait-ce que d’un caractère dans le prompt. L’ordre des champs et les espaces ne comptent pas
Le prix à cet instantCinq minutes se sont écoulées, ou le prix a changé

40901 signifie que le devis ne correspond plus à la requête

Des entrées modifiées, une autre clé API, un devis expiré, un prix qui a changé ou un expectedCost différent du devis se manifestent tous de la même façon : l’acceptation échoue avec 40901, et rien n’est facturé. Demandez un nouveau devis et faites-le confirmer à nouveau. Ne retirez pas quoteId et expectedCost pour faire passer la requête sans prix validé.

POST /api/v1/jobs/stream, le flux de texte natif, accepte un devis de la même manière ; voir Texte et streaming.

Reprendre après une réponse perdue

Si une soumission a dépassé le délai ou si la connexion a été coupée, vous ne savez pas si elle a été acceptée. Pour createTask, retry et POST /v1/videos :

  1. Renvoyez la requête d’origine avec son Idempotency-Key d’origine, en utilisant la même clé API. Vous récupérez la tâche d’origine, dans son état actuel, et vous n’êtes pas facturé deux fois.
  2. Ne créez pas une autre tâche avec une nouvelle clé. Une nouvelle clé signifie une nouvelle génération et une nouvelle facturation.
  3. Le rejeu d’une requête déjà acceptée reste valable après l’expiration du devis. L’expiration conditionne l’acceptation, pas la tâche que cette acceptation a créée.
  4. Un 409 ne veut pas dire « non créée ». Soit la requête a changé (c’est un nouveau travail, qui demande une nouvelle clé), soit elle a été envoyée avec une autre clé API du même compte (renvoyez-la avec la clé d’origine). Voir Idempotence.
  5. Lisez cost et settled dans recordInfo pour connaître le montant final.

Les requêtes de texte et de streaming ne se récupèrent pas ainsi

La réponse à une requête de texte (/api/v1/jobs/stream, et les points de terminaison de texte sous /v1 et /v1beta) vous est envoyée au fur et à mesure qu’elle est générée et n’est pas stockée. Renvoyer une clé déjà acceptée renvoie une erreur au lieu de la réponse : 400 si le corps est identique, 409 s’il est différent. Rien de plus n’est facturé, mais la réponse perdue ne peut pas être récupérée. Pour obtenir de nouveau une réponse, envoyez la requête avec une nouvelle clé et payez-la. Voir, dans Idempotence, quels points de terminaison lisent l’en-tête.

Une estimation n’est pas un règlement

estimatedCost est le montant que nous prévoyons de facturer. Un marqueur de fin de texte dans un flux indique seulement que les octets ont cessé d’arriver. Ni l’un ni l’autre ne prouve que la facturation est définitive. Pour les tâches, c’est settled: true accompagné de cost dans recordInfo qui le prouve. Les appels de texte ne renvoient pas d’identifiant de tâche : retrouvez leur montant en listant les tâches avec la même clé API (GET /api/v1/jobs) ou dans Console → Journal, et considérez cost comme définitif dès que settled vaut true.

Les devis dans les outils officiels

La CLI et le serveur MCP demandent un devis et interrogent une personne avant chaque appel payant, vous n’avez donc pas à construire cette étape vous-même :

  • CLI : spicyapi tasks quote donne le prix d’une requête ; spicyapi tasks create redemande un devis, affiche le montant et vous demande votre accord avant de créer la tâche. Voir Coûts, confirmation et sécurité.
  • MCP : l’assistant peut demander des devis librement, mais la création d’une tâche vous est soumise, avec le prix, via votre client IA. Voir Coûts, confirmation et sécurité.
  • SDK : quoteTask renvoie le devis ; passez son quoteId et son estimatedCost à createTask ou à run.

Un agent ne doit pas confirmer à la place de l’utilisateur

La confirmation existe pour qu’une personne décide. Un agent qui y répond lui-même, ou un client réglé pour tout approuver automatiquement, a supprimé la seule limite de dépense sur ce chemin.

Compatibilité texte et vidéo

SpicyAPI parle aussi les formats OpenAI, Anthropic et Google Gemini pour les modèles de texte, et le format OpenAI Videos pour la vidéo. La liste complète des points de terminaison figure dans la référence de l’API ; les requêtes, flux et erreurs de chaque protocole sont décrits dans Texte et streaming.

URL de base. Le format OpenAI utilise https://api.spicyapi.ai/v1. Les SDK Anthropic et Google GenAI ajoutent eux-mêmes /v1 ou /v1beta : indiquez donc https://api.spicyapi.ai comme URL de base.

Identifiant. Une seule clé API pour tous, dans l’en-tête Authorization: Bearer. L’en-tête x-api-key utilisé par le SDK Anthropic et l’en-tête x-goog-api-key utilisé par le SDK Google GenAI sont aussi acceptés. Un ?key= dans l’URL ne l’est jamais.

Modèle. Choisissez un modèle exact dans le catalogue en direct. La prise en charge des outils, des messages avec image et des options de génération dépend du schéma de ce modèle, pas du protocole choisi.

Forme de la réponse. Chaque protocole renvoie sa propre enveloppe, et non l’enveloppe {code, msg, data, request_id} de la plateforme.

Champs de raisonnement

Les modèles de chat qui exposent leur texte de raisonnement peuvent renvoyer une chaîne facultative dans message.reasoning_content, ou dans delta.reasoning_content en streaming. Pour poursuivre après un appel d’outil, vous pouvez la conserver dans le message assistant correspondant, lorsque le schéma du modèle en direct le permet.

usage.completion_tokens_details.reasoning_tokens décrit la part de raisonnement déjà incluse dans completion_tokens : ne l’ajoutez pas une seconde fois. Tous les modèles ne renvoient pas de texte de raisonnement ni ce détail des tokens.

Deux formes à connaître avant de commencer

  • Responses exige la conversation complète dans input. previous_response_id n’est pas pris en charge.
  • Videos accepte du JSON avec model, prompt, input_reference, seconds et size, qui sont traduits vers les champs propres au modèle. L’id de vidéo renvoyé est aussi un identifiant de tâche accepté par recordInfo. Son point de terminaison de contenu redirige, avec un HTTP 302, vers une URL signée de courte durée.

Les API compatibles facturent au prix en vigueur à l’acceptation

quoteId et expectedCost ne s’appliquent qu’à jobs/createTask et jobs/stream. /v1 et /v1beta appliquent le prix en vigueur au moment où la requête est acceptée et refusent ces deux champs : il n’y a donc pas de confirmation de prix appel par appel sur ce chemin. Quand un processus doit confirmer une limite de facturation, utilisez l’API de tâches native ; pour borner tout ce qu’une clé peut dépenser, fixez ses plafonds quotidien, mensuel et cumulé, comme expliqué dans Authentification.

Pour un exemple de chat en streaming avec les clients officiels OpenAI, Anthropic et Google, voir Utiliser un SDK officiel. La CLI et le serveur MCP soumettent et suivent des tâches natives ; ils ne diffusent pas les tokens de chat en streaming.

Sur cette page