Aller au contenu

Signer les requêtes

Toutes les requêtes portent votre clé : Authorization: Bearer tano_sandbox_…. Les créations (POST d’un dossier, d’une session, d’un webhook…) demandent en plus trois en-têtes :

En-tête Valeur
Idempotency-Key un identifiant unique par intention (un UUID)
X-Tano-Timestamp l’heure actuelle, en secondes Unix
X-Tano-Signature v2= suivi de la signature, en hexadécimal
message = horodatage + "." + MÉTHODE + "." + cible + "." + corps
signature = "v2=" + hex(HMAC-SHA256(secret, message))
  • secret : la dernière partie de votre clé (tano_sandbox_<identifiant>_<secret>).
  • MÉTHODE : en majuscules (POST).
  • cible : le chemin tel qu’envoyé, chaîne de requête comprise (/v1/cases).
  • corps : les octets exacts que vous envoyez.
import hashlib, hmac, json, time, uuid, urllib.request
CLE = "tano_sandbox_…"
SECRET = CLE.rsplit("_", 1)[1]
def creer(cible: str, donnees: dict) -> dict:
corps = json.dumps(donnees).encode()
horodatage = str(int(time.time()))
message = f"{horodatage}.POST.{cible}.".encode() + corps
signature = "v2=" + hmac.new(SECRET.encode(), message, hashlib.sha256).hexdigest()
requete = urllib.request.Request(
"https://api.tano.africa" + cible,
data=corps,
method="POST",
headers={
"Authorization": f"Bearer {CLE}",
"Content-Type": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
"X-Tano-Timestamp": horodatage,
"X-Tano-Signature": signature,
},
)
with urllib.request.urlopen(requete) as reponse:
return json.load(reponse)
dossier = creer("/v1/cases", {"flow_name": "identite_ci", "country": "CI"})

La requête doit arriver dans une fenêtre de cinq minutes autour de l’heure de Tano. Au-delà : signature_expired. Gardez l’horloge de vos serveurs synchronisée (NTP). Une même signature ne se rejoue pas : signature_replayed.

Un réseau coupe parfois après que Tano a reçu la requête : vous ne savez pas si le dossier existe. Réessayez avec la même Idempotency-Key : Tano rend la même réponse que la première fois, sans créer de doublon. Réutiliser une clé pour une autre requête est refusé (idempotency_key_reused).

Règle simple : une clé d’idempotence par intention (« ouvrir le dossier du client 4821 »), conservée tant que vous réessayez cette intention.

© 2026 Qalebasse · Tano, plateforme de confiance numériquetano.africaDemander un accès[email protected]