VPS KVM canadien à Montréal dès 8,50 CAD/mois

API

Erreurs, limites et rejeu

La forme d'un refus, les codes stables, les seaux de débit et l'idempotence.

Un refus est une réponse comme une autre : il a une forme stable, un code que votre programme peut lire, et un identifiant que le support peut retrouver. Rien d'utile ne se cache dans le texte du message.

La forme d'un refus

bash
{
  "error": {
    "code": "insufficient_credit",
    "message": "This order needs 0.44 CAD of credit; the balance is 0.12 CAD.",
    "details": { "required": "0.44", "balance": "0.12", "missing": "0.32", "currency": "CAD" },
    "request_id": "req_8fh2kq4m1x0a"
  }
}

Décidez sur code, jamais sur message : le message est en anglais, destiné à un journal, et peut être reformulé. Le code, lui, entre dans le contrat. details porte de quoi agir — ici, le montant exact à recharger.

Chaque réponse, réussie ou non, porte un en-tête X-Request-Id. Citez-le si vous nous écrivez : on retrouve l'appel.

Les codes

De nouveaux codes peuvent apparaître. Traitez un code inconnu comme un échec ordinaire de sa classe HTTP.

CodeHTTP
missing_token401
invalid_api_key401
key_disabled401
key_expired401
insufficient_scope403
ip_not_allowed403
email_not_verified403
account_suspended403
forbidden403
validation_failed400
not_found404
request_refused422
insufficient_credit402
budget_cap_reached402
payment_required402
quota_reached409
service_suspended409
action_conflict409
idempotency_conflict409
hostname_taken409
order_in_progress409
too_many_pending_invoices409
coupon_not_found422
coupon_max_uses422
plan_unavailable_in_region422
image_unavailable_in_region422
image_incompatible_with_plan422
out_of_stock422
billing_mode_unavailable422
provisioning_failed500
rate_limited429
backend_unavailable503
internal_error500

Les seaux de débit

Par clé : 120 lectures par minute, 20 actions par minute, et 10 créations ou réinstallations par heure. Une réinstallation détruit un disque et reconstruit une machine : elle relève du même seau que les créations.

Chaque réponse porte X-RateLimit-Limit et X-RateLimit-Remaining pour le seau concerné ; un refus rend 429 avec Retry-After. Un garde plus large s'applique aussi par adresse, avant authentification : un client normal ne le rencontre jamais, un script qui devine des jetons, si.

Rejouer sans dupliquer

POST /v1/vms exige un en-tête Idempotency-Key : une valeur de votre choix, unique par commande. Si votre requête expire sans réponse, vous ne savez pas si la machine a été créée — la rejouer avec la même clé vous rend la première réponse, telle quelle, avec Idempotency-Replayed: true.

Trois cas, un seul est un rejeu : même clé et même corps, on ressert ; même clé et corps différent, c'est une erreur de votre côté et on refuse (409 idempotency_conflict) ; même clé pendant que la première tourne encore, on refuse aussi plutôt que d'exécuter les deux. Les clés sont gardées 24 heures.

Les actions asynchrones

Provisionner, réinstaller, allumer : rien de tout cela n'est instantané. Ces appels rendent 202 et un objet action, que l'on sonde jusqu'à ce que son statut quitte running.

bash
{ "id": 90112, "type": "create", "status": "error", "vm_id": 4312,
  "source": "api",
  "error": { "code": "provisioning_failed",
             "message": "No IPv4 address left in the pool for this region." } }

Une action ne reste pas ouverte indéfiniment : passé six heures sans conclusion — une tâche perdue, une machine supprimée avant qu'on relise son sort — elle passe en error avec le code internal_error. Une boucle de sondage finit donc toujours par sortir.

L'historique d'une machine se lit sur GET /v1/vms/{id}/actions, et il est complet : un clic dans la console y figure aussi, avec source: console.

Support & discussions

Questions techniques, retours d'incidents ou discussions d'infrastructure, l'équipe est présente sur Discord, Telegram, X et IRC.