DÉVELOPPEURS / OPENAPI v1
Donnez à votre application
le sens de l’identité.
Guide de l’API de reconnaissance Maopu
De la première photo inscrite à la recherche d’identité : utilisez HTTP pour créer des registres, gérer les tâches et retrouver des candidats.
Documentation publique · Sans connexion Avant la première requête
- Connectez-vous à la console, créez un projet et copiez son UUID complet.
- Créez une clé API de projet, configurez ses autorisations et conservez le secret affiché une seule fois.
- Créez une identité, conservez l’id retourné et envoyez les photos d’inscription.
- Vérifiez la liste des tâches. Après l’inscription, envoyez une image de recherche pour obtenir les correspondances classées.
Dans ces exemples, {{base_url}}est l’adresse HTTPS de votre service API et {{api_key}} est votre clé de projet. Obtenez l’adresse auprès de votre déploiement ou fournisseur. Ce site héberge la documentation, pas les requêtes métier /v1.
Les exemples cURL utilisent les continuations Bash. Sous Windows, importez-les dans Postman via Import → Raw text, définissez base_url et api_key et resélectionnez les fichiers. Exécutez Python sur le serveur avec requests et les variables d’environnement configurés.
AUTHENTIFICATION
Identifiants limités au projet
Les endpoints métier acceptent Authorization: Bearer mk_live_… ou le jeton de connexion du propriétaire. Chaque clé est liée à un projet et à ses autorisations.
| Autorisation | Opérations autorisées |
|---|
cats:read | Lire les identités, listes d’images et images |
cats:write | Gérer les identités, inscrire des images, choisir les photos principales et les candidats |
recognition:write | Rechercher des identités félines |
tasks:read | Lire les tâches, résultats, résumés et aperçus |
L’authentification vérifie l’état, la révocation, l’expiration et les adresses IP. L’accès complet comprend les quatre autorisations ; un tableau scopes vide à la création les accorde toutes. La relance accepte cats:write ou recognition:write.
Projets, paramètres, clés, portefeuilles, facturation et consommation exigent un jeton de connexion, pas une clé API. Stockez les secrets dans les variables d’environnement du serveur.
PROCESSUS
Inscription asynchrone et recherche de résultats
L’inscription renvoie HTTP 202 et task_id ; vectors_added: 0 est normal à ce stade. Les images deviennent recherchables après extraction. La reconnaissance est prioritaire et attend l’inférence avant de répondre.
queued → running → completed
→ waiting_user → selection → queued
→ failed → retry → queuedInterrogez GET /tasks?limit=10&offset=0 toutes les quelques secondes et retrouvez task_id par id. Il n’existe pas d’endpoint de détail GET /tasks/ {task_id} . Les tâches sont triées de la plus récente à la plus ancienne. Paginez avec offset et dédupliquez par identifiant.
Une inscription avec plusieurs chats peut passer à waiting_user. Consultez les images candidates, envoyez candidate_index via selection ou abandonnez via cancel. Seules les tâches échouées peuvent être relancées.
Un délai dépassé ne signifie pas un échec. Consultez les tâches avant de renvoyer l’image pour éviter doublons et frais. Il n’existe pas de déduplication générale par Idempotency-Key.
LIMITES ET ERREURS
Limites, facturation et erreurs
Par défaut, chaque clé autorise par seconde 2 reconnaissances, 10 inscriptions/écritures et 20 lectures. Ces limites sont configurables. Sur 429, respectez Retry-After. Les réponses JSON normales exposent X-RateLimit-Limit et X-RateLimit-Remaining.
La limite d’image par défaut est de 15 MiB, configurable. JPEG, PNG et WebP sont acceptés. L’extraction des représentations vectorielles est facturée ; tarifs et crédits sont dans la console. detail peut être une chaîne, un objet ou un tableau de validation. Conservez le statut HTTP et X-Request-Id.
| HTTP | Code d’erreur / détail | Description |
|---|
| 401 | invalid_api_key | Format ou secret invalide, ou clé inconnue |
| 401 | expired_api_key | La clé a expiré |
| 403 | api_key_disabled / api_key_revoked | La clé est désactivée ou révoquée |
| 403 | project_mismatch | La clé appartient à un autre projet |
| 403 | scope_denied | Autorisation requise manquante |
| 403 | ip_not_allowed | Adresse IP source non autorisée |
| 404 | Not found | Projet, identité, image ou tâche introuvable |
| 409 | Conflict | L’état de la tâche interdit cette opération |
| 413 | Image is too large | L’image dépasse la taille autorisée |
| 415 | Unsupported media type | Seuls JPEG, PNG et WebP sont acceptés |
| 422 | Validation error | Vérifiez les champs requis, types et plages |
| 429 | rate_limit_exceeded | Réduisez la concurrence et respectez Retry-After |
| 503 | Recognition task failed | Échec de l’inférence ; vérifiez la tâche avant de relancer |
RÉFÉRENCE API / v1
Reconnaître un chat
POST/v1/projects/{project_id}/search
Autorisation requise : recognition:write. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
Utilisez multipart/form-data avec le champ fichier obligatoire image . Un fichier JPEG, PNG ou WebP par requête. Laissez le client générer Content-Type et boundary.
Paramètres et résultats
top_k est un entier de 1 à 100, par défaut 5 (configurable) ; threshold est un seuil facultatif entre −1 et 1. Sans valeur, le seuil du modèle s’applique.
matches contient les candidats classés par similarité ; unknown=true indique qu’aucune identité fiable ne dépasse le seuil. Dans candidates , score mesure la détection, pas la similarité d’identité. Détecter un visage ne suffit pas à identifier le chat.
{
"cat_count": 1,
"route": "face",
"face_detected": true,
"unknown": true,
"matches": [],
"candidates": [
{
"index": 0,
"score": 0.95,
"route": "face",
"face_detected": true,
"unknown": true,
"matches": []
}
],
"task_id": "<task_id>"
}Structure de réponse illustrative, pas un résultat réel.
curl --request POST '{{base_url}}/v1/projects/{project_id}/search?top_k=5' \
--header 'Authorization: Bearer {{api_key}}' \
--form '[email protected];type=image/jpeg'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
with open("cat.jpg", "rb") as image:
response = requests.post(
base_url + "/v1/projects/{project_id}/search?top_k=5",
headers={"Authorization": f"Bearer {api_key}"},
files={"image": ("cat.jpg", image, "image/jpeg")},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Créer une identité
POST/v1/projects/{project_id}/cats
Autorisation requise : cats:write. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
name contient de 1 à 100 caractères et est obligatoire à la création ; metadata est un objet JSON ; active vaut true par défaut. Envoyez seulement les champs modifiés.
curl --request POST '{{base_url}}/v1/projects/{project_id}/cats' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'Content-Type: application/json' \
--data '{"name":"Mimi","metadata":{},"active":true}'
Voir l’exemple Python
import os
import json
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.post(
base_url + "/v1/projects/{project_id}/cats",
headers={"Authorization": f"Bearer {api_key}"},
json=json.loads("{\"name\":\"Mimi\",\"metadata\":{},\"active\":true}"),
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Lister les identités
GET/v1/projects/{project_id}/cats
Autorisation requise : cats:read. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
curl --request GET '{{base_url}}/v1/projects/{project_id}/cats' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.get(
base_url + "/v1/projects/{project_id}/cats",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Modifier une identité
PATCH/v1/projects/{project_id}/cats/{cat_id}
Autorisation requise : cats:write. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
name contient de 1 à 100 caractères et est obligatoire à la création ; metadata est un objet JSON ; active vaut true par défaut. Envoyez seulement les champs modifiés.
curl --request PATCH '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'Content-Type: application/json' \
--data '{"name":"Mimi","active":true}'
Voir l’exemple Python
import os
import json
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.patch(
base_url + "/v1/projects/{project_id}/cats/{cat_id}",
headers={"Authorization": f"Bearer {api_key}"},
json=json.loads("{\"name\":\"Mimi\",\"active\":true}"),
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Supprimer une identité
DELETE/v1/projects/{project_id}/cats/{cat_id}
Autorisation requise : cats:write. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
Supprimer une identité supprime ses images et vecteurs ; supprimer une image supprime ses vecteurs. La suppression d’identité renvoie 204 sans corps.
curl --request DELETE '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.delete(
base_url + "/v1/projects/{project_id}/cats/{cat_id}",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Inscrire une image
POST/v1/projects/{project_id}/cats/{cat_id}/images
Autorisation requise : cats:write. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
Utilisez multipart/form-data avec le champ fichier obligatoire image . Un fichier JPEG, PNG ou WebP par requête. Laissez le client générer Content-Type et boundary.
Renvoie 202 queued avec task_id. Suivez l’inscription dans la liste des tâches.
curl --request POST '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}/images' \
--header 'Authorization: Bearer {{api_key}}' \
--form '[email protected];type=image/jpeg'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
with open("cat.jpg", "rb") as image:
response = requests.post(
base_url + "/v1/projects/{project_id}/cats/{cat_id}/images",
headers={"Authorization": f"Bearer {api_key}"},
files={"image": ("cat.jpg", image, "image/jpeg")},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Lister les images
GET/v1/projects/{project_id}/cats/{cat_id}/images
Autorisation requise : cats:read. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
curl --request GET '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}/images' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.get(
base_url + "/v1/projects/{project_id}/cats/{cat_id}/images",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Obtenir une image
GET/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}/content
Autorisation requise : cats:read. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
La réponse réussie contient une image binaire, pas du JSON.
curl --request GET '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}/content' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.get(
base_url + "/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}/content",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Définir la photo principale
PATCH/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}/primary
Autorisation requise : cats:write. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
curl --request PATCH '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}/primary' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.patch(
base_url + "/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}/primary",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Supprimer une image
DELETE/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}
Autorisation requise : cats:write. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
Supprimer une identité supprime ses images et vecteurs ; supprimer une image supprime ses vecteurs. La suppression d’identité renvoie 204 sans corps.
curl --request DELETE '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.delete(
base_url + "/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Lister les tâches
GET/v1/projects/{project_id}/tasks
Autorisation requise : tasks:read. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
limit va de 1 à 200, par défaut 100 ; offset est supérieur ou égal à 0, par défaut 0. Le tableau retourné contient les états et result.
curl --request GET '{{base_url}}/v1/projects/{project_id}/tasks?limit=10&offset=0' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.get(
base_url + "/v1/projects/{project_id}/tasks?limit=10&offset=0",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Résumé de la tâche
GET/v1/projects/{project_id}/tasks/summary
Autorisation requise : tasks:read. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
curl --request GET '{{base_url}}/v1/projects/{project_id}/tasks/summary' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.get(
base_url + "/v1/projects/{project_id}/tasks/summary",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Image de recherche
GET/v1/projects/{project_id}/tasks/{task_id}/query
Autorisation requise : tasks:read. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
La réponse réussie contient une image binaire, pas du JSON.
curl --request GET '{{base_url}}/v1/projects/{project_id}/tasks/{task_id}/query' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.get(
base_url + "/v1/projects/{project_id}/tasks/{task_id}/query",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Image candidate
GET/v1/projects/{project_id}/tasks/{task_id}/candidates/{candidate_index}
Autorisation requise : tasks:read. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
La réponse réussie contient une image binaire, pas du JSON.
curl --request GET '{{base_url}}/v1/projects/{project_id}/tasks/{task_id}/candidates/{candidate_index}' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.get(
base_url + "/v1/projects/{project_id}/tasks/{task_id}/candidates/{candidate_index}",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Choisir le candidat à inscrire
POST/v1/projects/{project_id}/tasks/{task_id}/selection
Autorisation requise : cats:write. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
Réservé aux inscriptions en waiting_user. Les autres états renvoient 409. candidate_index est un entier non négatif.
curl --request POST '{{base_url}}/v1/projects/{project_id}/tasks/{task_id}/selection' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'Content-Type: application/json' \
--data '{"candidate_index":0}'
Voir l’exemple Python
import os
import json
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.post(
base_url + "/v1/projects/{project_id}/tasks/{task_id}/selection",
headers={"Authorization": f"Bearer {api_key}"},
json=json.loads("{\"candidate_index\":0}"),
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Abandonner la sélection
POST/v1/projects/{project_id}/tasks/{task_id}/cancel
Autorisation requise : cats:write. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
Réservé aux inscriptions en waiting_user. Les autres états renvoient 409. candidate_index est un entier non négatif.
curl --request POST '{{base_url}}/v1/projects/{project_id}/tasks/{task_id}/cancel' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.post(
base_url + "/v1/projects/{project_id}/tasks/{task_id}/cancel",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
RÉFÉRENCE API / v1
Relancer une tâche échouée
POST/v1/projects/{project_id}/tasks/{task_id}/retry
Autorisation requise : cats:write / recognition:write. Le jeton du propriétaire est aussi accepté. Remplacez tous les paramètres de chemin par les vrais identifiants.
Seules les tâches échouées dont la source est conservée peuvent être relancées. Succès : 202.
curl --request POST '{{base_url}}/v1/projects/{project_id}/tasks/{task_id}/retry' \
--header 'Authorization: Bearer {{api_key}}'
Voir l’exemple Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Remplacez {project_id}, {cat_id}, etc. par les vrais identifiants.
response = requests.post(
base_url + "/v1/projects/{project_id}/tasks/{task_id}/retry",
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
response.raise_for_status()
print(response.content)
Chemins, corps et autorisations sont synchronisés avec la documentation existante. Les exemples ne contiennent que des paramètres fictifs, jamais de secrets réels.