L'API d'Undrop
Cherchez sur Undrop depuis vos propres programmes : envoyez le nom d'un produit, un lien de boutique ou d'image, ou des photos, et recevez les endroits où il se vend moins cher.
Obtenir une cléObtenir une clé
Créez une clé sur votre page Compte, dans la section API. Il vous faut un compte dont l'adresse e-mail est confirmée.
Vous pouvez avoir 3 clés à la fois. Une clé n'est affichée qu'une fois, à sa création : copiez-la à ce moment-là. Vous pouvez révoquer une clé depuis la même page ; les programmes qui l'utilisent cessent aussitôt de fonctionner.
Authentification
Envoyez la clé dans l'en-tête Authorization de chaque requête : Authorization: Bearer ud_….
N'utilisez la clé que depuis votre serveur. Ne la mettez jamais dans du code front-end, une page Web ou une application que vous distribuez : n'importe qui pourrait l'y lire. L'API n'envoie aucun en-tête CORS, les navigateurs ne peuvent donc pas l'appeler. Si une clé fuit, révoquez-la et créez-en une autre.
Lancer une recherche
POST https://undrop.app/api/public/v1/searches accepte ce qu'accepte le site. Chaque recherche se fait comme sur le site, au niveau standard : l'analyse avancée n'est pas proposée par l'API.
curl https://undrop.app/api/public/v1/searches \
-H "Authorization: Bearer $UNDROP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "wireless earbuds with charging case", "country": "US"}'curl https://undrop.app/api/public/v1/searches \
-H "Authorization: Bearer $UNDROP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://shop.example/products/neck-fan", "country": "US"}'curl https://undrop.app/api/public/v1/searches \
-H "Authorization: Bearer $UNDROP_API_KEY" \
-F "images=@ad-screenshot.jpg" \
-F country=US \
-F referencePrice=39.99curl https://undrop.app/api/public/v1/searches \
-H "Authorization: Bearer $UNDROP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "repair",
"part": "door seal",
"brand": "Bosch",
"model": "WAT28400",
"imageUrls": ["https://example.com/rating-plate.jpg"]
}'curl https://undrop.app/api/public/v1/searches \
-H "Authorization: Bearer $UNDROP_API_KEY" \
-F kind=repair \
-F "part=door seal" \
-F "images=@rating-plate.jpg" \
-F "images=@old-part.jpg"| Champ | Ce qu'il accepte |
|---|---|
query | Le nom du produit, de 2 à 200 caractères. |
url | Un lien http(s) vers une page de boutique, une vidéo ou une image. |
images | Des fichiers d'image, en multipart : jusqu'à 8 pour une recherche de prix, 3 pour une pièce, 4,4 Mo en tout. |
kind | repair pour chercher une pièce de rechange. À omettre pour une recherche de prix. |
part, brand, model | Les mots d'une recherche de pièce, chacun facultatif, jusqu'à 120 caractères. Envoyez au moins une photo ou l'un d'eux. |
imageUrls | Les photos d'une pièce par leurs liens http(s), en JSON (jusqu'à 3) : nous les récupérons comme un envoi. |
country | Facultatif : deux lettres majuscules, comme US : le pays pour lequel les annonces sont comparées. Sinon celui de votre compte, ou celui d'où vient la requête. |
currency | Facultatif : trois lettres majuscules, comme USD. Sinon celle de votre compte, ou celle du pays. |
referencePrice | Facultatif, pour une recherche de prix : le prix que vous avez vu, un nombre supérieur à 0. Les économies sont calculées à partir de lui. |
Obtenir les résultats
Une recherche prend de quelques secondes à environ une minute et demie. Le POST répond aussitôt par 202 Accepted : la recherche, son statut running, et son adresse dans l'en-tête Location.
HTTP/1.1 202 Accepted
Location: https://undrop.app/api/public/v1/searches/0199de4a-6f3b-7c21-9a8e-5b2d1c0f4e37
Retry-After: 3
Content-Type: application/json; charset=utf-8
{"id": "0199de4a-6f3b-7c21-9a8e-5b2d1c0f4e37", "kind": "price", "status": "running", …, "results": []}Pour obtenir les résultats en un seul appel, ajoutez Prefer: wait : la réponse attend la fin de la recherche, 110 secondes au plus, et arrive avec 200 OK. Prefer: wait=30 attend 30 secondes au plus. Si la recherche tourne encore à la fin de l'attente, la réponse est 202, comme sans l'en-tête.
curl https://undrop.app/api/public/v1/searches \
-H "Authorization: Bearer $UNDROP_API_KEY" \
-H "Content-Type: application/json" \
-H "Prefer: wait" \
-d '{"query": "wireless earbuds with charging case", "country": "US"}'Sinon, lisez la recherche à son adresse jusqu'à ce que son statut ne soit plus running. Tant qu'elle tourne, la réponse porte Retry-After: 3 : attendez ce nombre de secondes avant de la relire. Une clé ne lit que ses propres recherches : tout autre identifiant répond 404.
curl https://undrop.app/api/public/v1/searches/0199de4a-6f3b-7c21-9a8e-5b2d1c0f4e37 \
-H "Authorization: Bearer $UNDROP_API_KEY"La réponse
Une recherche, en JSON. Ses résultats sont les annonces payantes, dans l'ordre du site : la plus ressemblante d'abord, puis la moins chère.
| Champ | Type | Ce que c'est |
|---|---|---|
id | string | L'identifiant de la recherche. |
kind | string | price, ou repair pour une pièce de rechange. |
status | string | running, puis succeeded, partial (des sources n'ont pas répondu à temps), failed, refused (un contenu que nous ne cherchons pas) ou not_product (aucun produit trouvé). |
country | string | Le pays pour lequel les annonces sont comparées, en deux lettres. |
currency | string | La devise dans laquelle les prix sont convertis, en trois lettres. |
createdAt, completedAt | string, null | Dates ISO 8601 en UTC ; completedAt vaut null tant que la recherche tourne. |
error | object, null | { "code": … } quand la recherche s'est terminée sans résultat : l'un des codes de la section Erreurs. |
results | array | Les annonces payantes ; vide tant que la recherche tourne. |
Chaque résultat :
| Champ | Type | Ce que c'est |
|---|---|---|
id | string | L'identifiant de l'annonce. |
title | string | Le titre de l'annonce. |
source | string | La place de marché, comme aliexpress, temu ou amazon. |
store | string | Le nom de la boutique, tel que l'annonce le donne. |
price | object, null | amount et currency, dans la devise de la recherche quand la conversion est possible. Null quand le prix ne peut pas être affiché : ceux d'Amazon ne le sont jamais. |
imageUrl | string, null | La photo de l'annonce. |
link | string | Le lien d'Undrop vers l'annonce. Utilisez-le exactement tel quel. |
match | string | Sa ressemblance avec le produit : same, variant (une autre option du produit), similar, different ou unverified. |
isSupplier | boolean | Vendu sur une place de marché de fournisseurs, comme AliExpress ou Alibaba, plutôt que par un détaillant. |
savingsPct | number, null | De combien il coûte moins cher que le prix vu, en pourcentage, pour le même produit ou une autre option du produit. |
part | object | Recherche de pièce seulement : origin (oem, compatible, used ou unknown), verified (un original que nous pouvons garantir) et maker. |
{
"id": "0199de4a-6f3b-7c21-9a8e-5b2d1c0f4e37",
"kind": "price",
"status": "succeeded",
"country": "US",
"currency": "USD",
"createdAt": "2026-10-13T14:02:11.482Z",
"completedAt": "2026-10-13T14:02:39.907Z",
"error": null,
"results": [
{
"id": "0199de4a-8d20-7e1f-b3c4-2a6e9f1d0c58",
"title": "Wireless earbuds with charging case, Bluetooth 5.3",
"source": "aliexpress",
"store": "AliExpress",
"price": {
"amount": 8.49,
"currency": "USD"
},
"imageUrl": "https://images.example/earbuds-white.jpg",
"link": "https://undrop.app/go/0199de4a-8d20-7e1f-b3c4-2a6e9f1d0c58",
"match": "same",
"isSupplier": true,
"savingsPct": 71.6
},
{
"id": "0199de4a-8d20-7e1f-b3c4-31f07a4be912",
"title": "Wireless Earbuds, Bluetooth Headphones with Charging Case",
"source": "amazon",
"store": "Amazon",
"price": null,
"imageUrl": "https://images.example/earbuds-black.jpg",
"link": "https://undrop.app/go/0199de4a-8d20-7e1f-b3c4-31f07a4be912",
"match": "variant",
"isSupplier": false,
"savingsPct": null
}
]
}Limites
Chaque clé peut lancer 20 recherches par jour, comptées depuis minuit UTC, et 10 recherches par heure. Une recherche qui échoue ou ne trouve rien ne compte pas dans la journée. La lecture des recherches a sa propre limite, 100 lectures par heure : une clé à court de recherches reçoit quand même ses résultats. Une clé peut avoir 3 recherches en cours à la fois.
Ce sont les limites actuelles de chaque clé, et elles peuvent changer. Besoin de plus pour un projet ? Écrivez à fcarreau@gmail.com : nous pouvons relever les limites d'une clé.
Au-delà d'une limite, l'API répond 429 Too Many Requests, avec Retry-After (les secondes à attendre) et la raison dans details.reason : hourly_limit ou daily_quota.
{
"error": {
"code": "RATE_LIMITED",
"message": "This key has used today's 20 searches (UTC).",
"details": {
"reason": "daily_quota",
"limit": 20,
"used": 20,
"retryAfterSeconds": 35940
}
}
}Erreurs
Une erreur répond { "error": { "code", "message", "details" } }. Fiez-vous au code : le message est écrit pour des personnes, en anglais, et peut changer.
| Statut | Code | Quand |
|---|---|---|
| 400 | VALIDATION_FAILED | Un champ manque ou est incorrect, ou advanced a été demandé. |
| 400 | URL_NOT_ALLOWED | Le lien n'est pas une adresse http(s) publique. |
| 401 | UNAUTHORIZED | Aucune clé, ou une clé invalide ou révoquée. |
| 403 | FORBIDDEN | Le compte de la clé est suspendu. |
| 404 | NOT_FOUND | Aucune recherche avec cet identifiant pour cette clé. |
| 409 | SEARCH_IN_PROGRESS | La clé a déjà 3 recherches en cours. |
| 413 | PAYLOAD_TOO_LARGE | L'envoi dépasse 4,4 Mo. |
| 415 | UNSUPPORTED_MEDIA | Le lien d'une photo ne mène pas à une image. |
| 422 | URL_UNREACHABLE | Nous n'avons pas pu ouvrir le lien d'une photo. |
| 429 | RATE_LIMITED | Au-delà de la limite par heure ou par jour : voir Limites. |
| 503 | MAINTENANCE | Les recherches sont en pause pour maintenance. |
| 503 | COST_CAP_REACHED | Le service a atteint sa capacité pour la journée. |
| 500 | INTERNAL | Une erreur de notre côté. Réessayez plus tard. |
Une recherche qui se termine sans résultat en donne la raison dans error.code, comme URL_UNREACHABLE, NOT_A_PRODUCT, REFUSED ou ANALYSIS_UNAVAILABLE.
Historique des versions
v1, octobre 2026 : la première version. Recherches par nom, lien, photos et pièce de rechange ; réponses avec des liens payants seulement.