API
Pour les clients avec forfait · version 1
En bref
- Envoyez une photo et de 1 à 3 contours d’exemple; recevez chaque objet correspondant avec son contour.
- C’est le même comptage IA avancée que sur le site, avec les mêmes crédits : une photo typique utilise 1 crédit.
- Il vous faut une clé d’accès liée à un forfait mensuel. Demandez-en une.
- Pour un dossier de photos, utilisez notre script de traitement par lots plutôt que d’écrire du code (voir la fin de cette page).
Adresse et clé
Toutes les requêtes vont à https://afterthought-app-2026--tally-count-api.us-east.modal.run
avec votre clé dans l’en-tête Authorization: Bearer tk_…. Les corps sont en JSON. Gardez la clé sur votre
serveur, et non dans une page web ou une application que d’autres peuvent ouvrir : quiconque l’a peut dépenser ses crédits.
POST /count
Compte les objets d’une photo et débite ses crédits. Requête :
{
"image": "<JPEG, PNG ou WebP en base64>",
"examples": [[[x, y], [x, y], [x, y], ...]], // 1 à 3 contours, en pixels de la photo
"area": [[x, y], ...], // facultatif : compter seulement dans ce contour
"params": {"sizeTol": 0.3, "minScore": 0.5} // facultatif, voir plus bas
}
- examples : polygones de 3 à 400 points autour d’objets typiques, un par type (par exemple une petite et une grosse pilule). Un rectangle (4 points) autour de l’objet convient bien.
- area : omettez-le pour compter toute la photo.
- sizeTol : de combien un objet peut être plus grand ou plus petit que les exemples : 0.3 vaut ±30 %, au plus 2. Valeur par défaut : 0.1.
- minScore : le degré de certitude exigé du modèle, de 0 à 1. Valeur par défaut : 0.5; plus bas, il trouve plus d’objets, avec plus d’erreurs.
- Les photos de plus de 4096 pixels sur le côté le plus long sont réduites à cette taille avant le comptage. Les envoyer à 2400 pixels est plus rapide et donne le même résultat pour la plupart des photos. Gardez les requêtes sous 20 Mo.
Réponse (abrégée) :
{
"detections": [
{"x": 812.4, "y": 447.0, "w": 108.2, "h": 45.1, "angle": 3.2, "score": 0.91,
"example_index": 0, "polygon": [[x, y], ...], "negative": false, "lookalike": false},
...
],
"image_size": [1600, 900],
"billing": {"charged": 1, "tiles": 4, "source": "credits", "balance": 1999, "ref": "c_..."}
}
Le comptage est le nombre de détections où negative et lookalike sont tous deux faux. Les
positions sont en pixels de la photo envoyée; example_index indique à quel exemple un objet correspond.
POST /quote
Même corps que /count. Indique ce que coûterait le comptage, sans compter ni débiter :
{"credits": 1, "tiles": 4, "balance": 2000}.
GET /balance
Indique les crédits de la clé : {"credits": 2000, "key_valid": true, ...}.
Crédits, limites et erreurs
- Coût. Un crédit couvre jusqu’à 10 tuiles d’image. Le nombre de tuiles dépend de la petitesse des objets par
rapport à la photo : une photo typique demande 1 crédit, et une photo de très petits objets jusqu’à 10. Une photo qui
demanderait plus de 100 tuiles est refusée (
422 too_small) : envoyez une zone de comptage ou une photo prise de plus près. - Crédits mensuels. Les crédits de votre forfait sont remis à niveau au début de chaque mois. Les crédits de forfait inutilisés ne s’accumulent pas; les crédits achetés en plus, oui.
- Limites de débit. Les clés de forfait peuvent habituellement compter 30 photos par minute et 3000 par jour
(votre forfait peut différer). Au-delà, vous recevez
429avec un en-têteRetry-Afteren secondes. - Les comptages échoués ne sont pas facturés. Avec
502,503ou504, rien n’a été débité; attendez un peu et renvoyez la photo. Le premier comptage après une période calme peut prendre jusqu’à une minute, le temps que le serveur démarre. - Les erreurs sont en JSON, avec un message en anglais :
{"error": "payment_required", "message": "…"}. Les plus courantes :400 bad_request,402 payment_required(pas assez de crédits),422 too_small,429 rate_limited.
Exemple
En Python, avec le paquet requests :
import base64, requests
API = "https://afterthought-app-2026--tally-count-api.us-east.modal.run"
KEY = "tk_..." # clé de votre forfait
with open("bac.jpg", "rb") as f:
image = base64.b64encode(f.read()).decode()
body = {
"image": image,
"examples": [[[410, 220], [470, 220], [470, 262], [410, 262]]], # un boulon
"params": {"sizeTol": 0.3},
}
r = requests.post(API + "/count", json=body, headers={"Authorization": "Bearer " + KEY}, timeout=180)
r.raise_for_status()
trouves = [d for d in r.json()["detections"] if not d["negative"] and not d["lookalike"]]
print(len(trouves), "comptés")
Par lots : un dossier de photos
Notre script photo_counter_batch.py compte un dossier entier : il évalue d’abord le coût de chaque photo,
affiche le total, puis les compte une à une et produit results.csv avec une image annotée par photo. Tracez
les exemples une seule fois pour une caméra fixe, ou pour chaque photo. Nous envoyons le script avec la clé de votre
forfait; il demande Python 3.9 ou plus récent et pip install pillow certifi.
python photo_counter_batch.py photos/ --examples examples.json --key tk_... --size-tol 0.3
Vous préférez ne rien installer? Envoyez-nous les photos et nous faisons le traitement pour vous.
Vos photos
Les photos envoyées à l’API sont traitées exactement comme sur le site : comptées en mémoire et non conservées par nous. Voir Confidentialité et les conditions d’utilisation.