DESARROLLADORES / OPENAPI v1
Dale a tu aplicación
sentido de identidad.
Guía de la API de reconocimiento Maopu
Desde la primera imagen registrada hasta la búsqueda de identidad. Usa HTTP para crear registros, gestionar tareas y recuperar candidatos.
Documentación pública · Sin iniciar sesión Antes de la primera petición
- Inicia sesión en la consola, crea un proyecto y copia su UUID completo.
- Crea una clave API del proyecto, configura sus permisos y guarda el secreto que solo se muestra una vez.
- Crea una identidad, conserva el id recibido y sube imágenes de registro.
- Revisa las tareas. Tras completar el registro, sube una imagen de consulta para obtener coincidencias ordenadas.
En estos ejemplos, {{base_url}}es la dirección HTTPS de tu servicio API y {{api_key}} es la clave del proyecto. Obtén la dirección de tu configuración o proveedor. Este sitio aloja documentación, no peticiones de negocio /v1.
Los ejemplos cURL usan continuaciones Bash. En Windows, impórtalos en Postman con Import → Raw text, configura base_url y api_key y vuelve a seleccionar los archivos. Ejecuta Python en el servidor con requests instalado y variables de entorno configuradas.
AUTENTICACIÓN
Credenciales limitadas al proyecto
Los endpoints aceptan Authorization: Bearer mk_live_… o el token de sesión del propietario. Cada clave pertenece a un proyecto y accede según sus permisos.
| Permiso | Operaciones permitidas |
|---|
cats:read | Leer identidades, listas de imágenes y archivos |
cats:write | Gestionar identidades, registrar imágenes, elegir fotos principales y candidatos |
recognition:write | Buscar identidades de gatos |
tasks:read | Leer tareas, resultados, resúmenes y vistas previas |
Se verifican estado, revocación, caducidad y listas de IP. El acceso completo incluye los cuatro permisos; un arreglo scopes vacío al crear la clave concede los cuatro. Reintentar tareas acepta cats:write o recognition:write.
Proyectos, ajustes, claves, monederos, facturación y consumo requieren un token de sesión, no una clave API. Guarda secretos en variables de entorno del servidor.
PROCESO
Registro asíncrono y consulta de resultados
El registro devuelve HTTP 202 y task_id; vectors_added: 0 es normal en este momento. Las imágenes se pueden buscar tras la extracción. El reconocimiento tiene prioridad y espera la inferencia antes de responder.
queued → running → completed
→ waiting_user → selection → queued
→ failed → retry → queuedConsulta GET /tasks?limit=10&offset=0 cada pocos segundos y localiza task_id por id. No existe un endpoint de detalle GET /tasks/ {task_id} . Las tareas se ordenan de más reciente a más antigua. Pagina con offset y elimina duplicados por ID.
Registrar varios gatos puede producir waiting_user. Revisa las imágenes candidatas y envía candidate_index mediante selection, o abandona con cancel. Solo se reintentan tareas fallidas.
Un tiempo de espera agotado no implica fallo. Revisa las tareas antes de volver a subir imágenes para evitar trabajo y cargos duplicados. No hay deduplicación general mediante Idempotency-Key.
LÍMITES Y ERRORES
Límites, facturación y errores
Por defecto, cada clave permite por segundo 2 reconocimientos, 10 registros/escrituras y 20 lecturas. Son configurables. Ante 429, respeta Retry-After. Las respuestas JSON normales incluyen X-RateLimit-Limit y X-RateLimit-Remaining.
El límite de imagen predeterminado es 15 MiB y se puede configurar. Se admiten JPEG, PNG y WebP. La extracción de vectores se factura; consulta precios y créditos en la consola. detail puede ser texto, un objeto o un arreglo de validación. Conserva el estado HTTP y X-Request-Id.
| HTTP | Código de error / detalle | Descripción |
|---|
| 401 | invalid_api_key | Formato o secreto inválido, o clave desconocida |
| 401 | expired_api_key | La clave ha caducado |
| 403 | api_key_disabled / api_key_revoked | Clave desactivada o revocada |
| 403 | project_mismatch | La clave pertenece a otro proyecto |
| 403 | scope_denied | Falta el permiso requerido |
| 403 | ip_not_allowed | IP de origen no permitida |
| 404 | Not found | Proyecto, identidad, imagen o tarea no encontrados |
| 409 | Conflict | El estado de la tarea no permite esta operación |
| 413 | Image is too large | La imagen supera el límite de tamaño |
| 415 | Unsupported media type | Solo se admiten JPEG, PNG y WebP |
| 422 | Validation error | Revisa campos obligatorios, tipos y rangos |
| 429 | rate_limit_exceeded | Reduce la concurrencia y respeta Retry-After |
| 503 | Recognition task failed | Falló la inferencia; revisa la tarea antes de reintentar |
REFERENCIA API / v1
Reconocer un gato
POST/v1/projects/{project_id}/search
Permiso requerido: recognition:write. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
Usa multipart/form-data con el campo de archivo obligatorio image . Un JPEG, PNG o WebP por petición. Deja que el cliente genere Content-Type y boundary.
Parámetros y resultados
top_k es un entero de 1 a 100, por defecto 5 (configurable); threshold es un umbral opcional de −1 a 1. Si se omite, se usa el valor del modelo.
matches contiene candidatos ordenados por similitud; unknown=true indica que ninguna identidad fiable supera el umbral. En candidates , score es la puntuación de detección, no la similitud de identidad. Detectar un rostro no significa identificar al gato.
{
"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>"
}Estructura ilustrativa de respuesta, no un resultado real.
curl --request POST '{{base_url}}/v1/projects/{project_id}/search?top_k=5' \
--header 'Authorization: Bearer {{api_key}}' \
--form '[email protected];type=image/jpeg'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Crear una identidad
POST/v1/projects/{project_id}/cats
Permiso requerido: cats:write. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
name tiene de 1 a 100 caracteres y es obligatorio al crear; metadata es un objeto JSON; active es true por defecto. Envía solo los campos que cambian.
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}'
Ver ejemplo de Python
import os
import json
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Listar identidades
GET/v1/projects/{project_id}/cats
Permiso requerido: cats:read. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
curl --request GET '{{base_url}}/v1/projects/{project_id}/cats' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Actualizar una identidad
PATCH/v1/projects/{project_id}/cats/{cat_id}
Permiso requerido: cats:write. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
name tiene de 1 a 100 caracteres y es obligatorio al crear; metadata es un objeto JSON; active es true por defecto. Envía solo los campos que cambian.
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}'
Ver ejemplo de Python
import os
import json
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Eliminar una identidad
DELETE/v1/projects/{project_id}/cats/{cat_id}
Permiso requerido: cats:write. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
Eliminar una identidad elimina sus imágenes y vectores; eliminar una imagen elimina sus vectores. Eliminar una identidad devuelve 204 sin cuerpo.
curl --request DELETE '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Registrar una imagen
POST/v1/projects/{project_id}/cats/{cat_id}/images
Permiso requerido: cats:write. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
Usa multipart/form-data con el campo de archivo obligatorio image . Un JPEG, PNG o WebP por petición. Deja que el cliente genere Content-Type y boundary.
Devuelve 202 queued y task_id. Sigue el registro en la lista de tareas.
curl --request POST '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}/images' \
--header 'Authorization: Bearer {{api_key}}' \
--form '[email protected];type=image/jpeg'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Listar imágenes
GET/v1/projects/{project_id}/cats/{cat_id}/images
Permiso requerido: cats:read. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
curl --request GET '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}/images' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Obtener una imagen
GET/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}/content
Permiso requerido: cats:read. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
La respuesta correcta contiene una imagen binaria, no JSON.
curl --request GET '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}/content' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Elegir foto principal
PATCH/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}/primary
Permiso requerido: cats:write. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
curl --request PATCH '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}/primary' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Eliminar una imagen
DELETE/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}
Permiso requerido: cats:write. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
Eliminar una identidad elimina sus imágenes y vectores; eliminar una imagen elimina sus vectores. Eliminar una identidad devuelve 204 sin cuerpo.
curl --request DELETE '{{base_url}}/v1/projects/{project_id}/cats/{cat_id}/images/{image_id}' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Listar tareas
GET/v1/projects/{project_id}/tasks
Permiso requerido: tasks:read. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
limit va de 1 a 200, por defecto 100; offset es al menos 0, por defecto 0. El arreglo devuelto contiene estados y result.
curl --request GET '{{base_url}}/v1/projects/{project_id}/tasks?limit=10&offset=0' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Resumen de la tarea
GET/v1/projects/{project_id}/tasks/summary
Permiso requerido: tasks:read. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
curl --request GET '{{base_url}}/v1/projects/{project_id}/tasks/summary' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Imagen de consulta
GET/v1/projects/{project_id}/tasks/{task_id}/query
Permiso requerido: tasks:read. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
La respuesta correcta contiene una imagen binaria, no JSON.
curl --request GET '{{base_url}}/v1/projects/{project_id}/tasks/{task_id}/query' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Imagen candidata
GET/v1/projects/{project_id}/tasks/{task_id}/candidates/{candidate_index}
Permiso requerido: tasks:read. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
La respuesta correcta contiene una imagen binaria, no JSON.
curl --request GET '{{base_url}}/v1/projects/{project_id}/tasks/{task_id}/candidates/{candidate_index}' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Seleccionar candidato de registro
POST/v1/projects/{project_id}/tasks/{task_id}/selection
Permiso requerido: cats:write. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
Solo para registros en waiting_user. Otros estados devuelven 409. candidate_index es un entero no negativo.
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}'
Ver ejemplo de Python
import os
import json
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Abandonar la selección
POST/v1/projects/{project_id}/tasks/{task_id}/cancel
Permiso requerido: cats:write. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
Solo para registros en waiting_user. Otros estados devuelven 409. candidate_index es un entero no negativo.
curl --request POST '{{base_url}}/v1/projects/{project_id}/tasks/{task_id}/cancel' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
REFERENCIA API / v1
Reintentar una tarea fallida
POST/v1/projects/{project_id}/tasks/{task_id}/retry
Permiso requerido: cats:write / recognition:write. También acepta el token del propietario. Sustituye los marcadores de ruta por identificadores reales.
Solo se reintentan tareas fallidas con datos originales conservados. Devuelve 202 si tiene éxito.
curl --request POST '{{base_url}}/v1/projects/{project_id}/tasks/{task_id}/retry' \
--header 'Authorization: Bearer {{api_key}}'
Ver ejemplo de Python
import os
import requests
api_key = os.environ["MEOWID_API_KEY"]
base_url = os.environ["MEOWID_API_BASE"].rstrip("/")
# Sustituye {project_id}, {cat_id}, etc. por identificadores reales.
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)
Rutas, cuerpos y permisos se sincronizan desde la documentación existente. Los ejemplos contienen marcadores, nunca credenciales reales.