Referencia de la REST API#
Ultralytics Platform proporciona una REST API para acceder mediante programación a conjuntos de datos, imágenes, proyectos, modelos, entrenamiento, exportaciones e implementaciones.

# List the datasets owned by a workspace
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://platform.ultralytics.com/api/datasets/YOUR_USERNAMECada endpoint de abajo muestra la llamada client.<resource>.<method>(...) del SDK ultralytics-platform, generado a partir del mismo contrato que esta referencia.
Esta página ofrece un recorrido guiado por la API. La referencia generada y siempre actualizada está en platform.ultralytics.com/api/docs, y el documento legible por máquinas OpenAPI 3.2 que la alimenta se publica en platform.ultralytics.com/openapi.json. Ambos se generan directamente a partir del contrato del servidor, por lo que son la fuente de referencia cuando esta página y el esquema no coinciden.
Descripción general de la API#
La API se organiza en torno a los recursos principales de Platform:
| Recurso | Descripción | Operaciones principales |
|---|---|---|
| Conjuntos de datos | Colecciones de imágenes etiquetadas | CRUD, ingesta, versiones, clases, divisiones, clonar, copiar |
| Imágenes | Imágenes y etiquetas individuales | Leer, anotar, cambiar de división, eliminar, anotar automáticamente, difuminar caras |
| Proyectos | Espacios de trabajo para modelos | CRUD, clonar |
| Modelos | Puntos de control entrenados | CRUD, predecir, descargar, clonar, estado del entrenamiento |
| Entrenamiento | Trabajos de entrenamiento en la nube con GPU | Disponibilidad de GPU, iniciar, progreso, cancelar |
| Exportaciones | Trabajos de conversión de formato | Crear, listar, estado, cancelar |
| Implementaciones | Endpoints de inferencia dedicados | Crear, actualizar, iniciar/detener, predecir, métricas, registros |
| Agentes | Flujos de trabajo visuales guardados | Listar, guardar, eliminar |
| Papelera | Recursos eliminados de forma no permanente | Listar, restaurar, eliminar permanentemente |
| Almacenamiento | Integraciones de almacenamiento en la nube | Conectar, descubrir, explorar, desconectar |
| Cuenta | Plan, créditos, almacenamiento, perfil | Resumen de la cuenta, claves de API, uso del almacenamiento, búsqueda de usuarios |
| Facturación | Uso del plan y libro mayor | Resumen de uso, transacciones |
| Explorar | Búsqueda de contenido público | Buscar proyectos, conjuntos de datos e imágenes |
Autenticación#
La mayoría de los endpoints requieren una clave de API. Los endpoints que exponen contenido público —como leer un conjunto de datos, un proyecto o un modelo públicos, listar imágenes de conjuntos de datos públicos, ejecutar inferencias en un modelo público o buscar en Explorar— también aceptan solicitudes anónimas y simplemente devuelven más información cuando se proporciona una clave.
Obtener una clave de API#
- Ve a
Settings>API Keys - Haz clic en
Add Key, dejaUltralyticscomo proveedor, introduce un nombre y haz clic enCreate Key - Copia la clave generada
Consulta Claves de API para ver instrucciones detalladas.
Cabecera de autorización#
Incluye tu clave de API como token bearer:
Authorization: Bearer YOUR_API_KEYLas claves de API son el prefijo literal ul_ seguido de 40 caracteres hexadecimales, 43 caracteres en total (por ejemplo, ul_a1b2c3d4e5f6789012345678901234567890abcd). Las solicitudes sin cabecera, con una clave mal formada o con una clave revocada devuelven 401. Mantén tu clave en secreto: no la incluyas nunca en el control de versiones ni la compartas públicamente.
Ejemplo#
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://platform.ultralytics.com/api/account/summaryURL base#
Todos los endpoints de la API usan:
https://platform.ultralytics.com/apiRutas de recursos#
La mayoría de los recursos se identifican con los mismos nombres legibles que aparecen en las URL de Platform, no con ID de base de datos:
| Recurso | Ruta | Ejemplo |
|---|---|---|
| Conjunto de datos | /api/datasets/{owner}/{dataset} | /api/datasets/acme-vision/warehouse |
| Proyecto | /api/projects/{owner}/{project} | /api/projects/acme-vision/inspection |
| Modelo | /api/models/{owner}/{project}/{model} | /api/models/acme-vision/inspection/v3 |
| Despliegue | /api/deployments/{owner}/{deployment} | /api/deployments/acme-vision/edge-1 |
| Imagen | /api/images/{imageId} | /api/images/65f1c0a2b3d4e5f601234567 |
| Agente | /api/workflows?id={agentId} | /api/workflows?id=65f1c0a2b3d4e5f601234567 |
{owner}es un nombre de usuario personal o el identificador de un espacio de trabajo de equipo: entre 4 y 32 caracteres, alfanuméricos en minúsculas, con guiones simples entre segmentos.{dataset},{project},{model}y{deployment}siguen el mismo patrón de minúsculas separadas por guiones, con un máximo de 128 caracteres.{imageId},{exportId}y{agentId}son ID hexadecimales de 24 caracteres que devuelve la API.- Al cambiar el nombre de un recurso mediante
PATCH, se actualizan a la vez elnamevisible y el nombre de la URL, y la respuesta devuelve el nombre actual de la URL para que puedas seguir usándolo.
Aparte de la API de Agents, no hay ningún parámetro de consulta owner. Las rutas con ámbito de espacio de trabajo incluyen al propietario en la ruta, y los endpoints con ámbito de cuenta (/api/account/summary, /api/api-keys, /api/storage, /api/billing/*, /api/trash, /api/integrations/buckets) operan en el espacio de trabajo que emitió la clave de API. Para operar en un espacio de trabajo de equipo, usa una clave de API creada en ese espacio de trabajo o pasa owner a la API de Agents.
Límites de frecuencia#
La API aplica límites de ventana deslizante por clave de API. Cada ruta pertenece a una categoría, y cada categoría tiene un contador independiente, por lo que 20 solicitudes de predicción no consumen tu cuota predeterminada.
| Categoría | Límite | Se aplica a |
|---|---|---|
| Predeterminado | 100 solicitudes/min | Todas las rutas que no se indican a continuación |
| Entrenamiento | 10 solicitudes/min | POST /api/training/start |
| Subir | 10 solicitudes/min | URL de carga firmadas, finalización de cargas e ingesta de conjuntos de datos |
| Predecir | 20 solicitudes/min | Inferencia de modelos e implementaciones mediante rutas de la API de Platform |
| Exportar | 20 solicitudes/min | Listar y crear exportaciones de modelos, y crear o actualizar versiones de conjuntos de datos; leer una exportación de conjunto de datos (GET) y una exportación de modelo individual usa el límite predeterminado |
| Descargar | 30 solicitudes/min | Descargas de archivos de modelos |
| Mutación | 10 solicitudes/min | Listar claves de API, listar o conectar integraciones de almacenamiento en la nube, descubrir ubicaciones de almacenamiento y actualizar implementaciones (PATCH) |
| Hidratación | 20 solicitudes/min | POST /api/datasets/{owner}/{dataset}/images (obtener un conjunto de imágenes seleccionado) y GET /api/images/{imageId}/similar |
| Agrupamiento | 10 solicitudes/min | GET /api/datasets/{owner}/{dataset}/images/clustering y GET /api/models/{owner}/{project}/{model}/similar-images |
Las rutas de la plataforma exclusivas del navegador, como el pago de facturas y la gestión de equipos, tienen sus propios límites, que no se aplican al tráfico de claves de API.
Cuando se aplica una limitación, la API devuelve 429 tanto en las cabeceras como en el cuerpo JSON:
Retry-After: 12
X-RateLimit-Reset: 2026-02-21T12:34:56.000Z{
"error": "Rate limit exceeded, wait 12s",
"retryAfter": 12,
"resetAt": "2026-02-21T12:34:56.000Z"
}Endpoints dedicados (sin límite)#
Los endpoints dedicados no están sujetos a los límites de velocidad de las claves de API de la plataforma cuando llamas directamente al serviceUrl propio de la implementación (por ejemplo, https://predict-abc123.run.app/predict). El rendimiento depende entonces de la configuración del servicio implementado.
Cuando recibas un 429, espera Retry-After segundos (o hasta X-RateLimit-Reset) antes de volver a intentarlo. Consulta las preguntas frecuentes sobre los límites de velocidad para ver una implementación de retroceso exponencial.
Formato de respuesta#
Respuestas correctas#
Las respuestas son objetos JSON con campos específicos del recurso. No hay un contenedor genérico: los endpoints de lista devuelven una colección con nombre, normalmente junto con recuentos, y las mutaciones devuelven los identificadores modificados.
{
"datasets": [{ "id": "65f1c0a2b3d4e5f601234567", "owner": "acme-vision", "dataset": "warehouse" }],
"total": 1,
"region": "us"
}Las listas de recursos, las respuestas de creación y clonación, y algunas lecturas, como las de implementaciones, almacenamiento y papelera, también incluyen region (us, eu o ap), la región de almacenamiento de ese espacio de trabajo.
Respuestas de error#
Todas las respuestas de error son objetos JSON con un mensaje error:
{
"error": "Dataset not found"
}| Estado HTTP | Significado |
|---|---|
200 | Correcto |
201 | Creado |
202 | Aceptada; el trabajo continúa de forma asíncrona |
400 | Ruta, consulta o cuerpo de solicitud no válidos |
401 | Autenticación ausente o no válida |
402 | Créditos insuficientes (entrenamiento) |
403 | Permisos, plan o cuota insuficientes |
404 | Recurso no encontrado |
409 | Conflicto con el estado actual (nombre duplicado, trabajo en curso) |
413 | La entrada de predicción es demasiado grande |
422 | Las clases del modelo no coinciden con el conjunto de datos, o falta una clave del proveedor o este la ha rechazado (anotación automática) |
429 | Se ha superado el límite de velocidad |
500 | Error del servidor |
502 | Error en la llamada al servicio o proveedor ascendente |
503 | Servicio dependiente temporalmente no disponible |
Paginación#
El estilo de paginación depende de la colección:
| Estilo | Endpoints | Parámetros |
|---|---|---|
| Solo límite | Listas de conjuntos de datos, proyectos, modelos, exportaciones e implementaciones | limit |
| Desplazamiento y límite | Imágenes de conjuntos de datos, agrupación de imágenes, búsqueda en Explorar | offset, limit y, en la respuesta, hasMore |
| Cursor | Imágenes de conjuntos de datos (conjuntos de datos grandes) | cursor, includeTotal y nextCursor |
| Número de página | Papelera | page, limit y totalPages |
| Token de página opaco | Registros de implementación | pageToken y nextPageToken |
API de conjuntos de datos#
Crea, explora y gestiona conjuntos de datos de imágenes etiquetadas para entrenar modelos YOLO. Consulta la documentación de conjuntos de datos.
Listar conjuntos de datos#
GET /api/datasets/{owner}SDK de Python: client.datasets.list(owner)
Devuelve los conjuntos de datos públicos del propietario, además de los conjuntos de datos privados cuando tu clave puede ver ese espacio de trabajo.
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
limit | int | Número máximo de conjuntos de datos que se devolverán (predeterminado: 1000, máximo: 1000) |
includeSamples | booleano | Incluir vistas previas de imágenes de muestra (predeterminado: true) |
includeImageUrls | booleano | Incluir URL alternativas de imágenes de muestra a tamaño completo (predeterminado: false) |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://platform.ultralytics.com/api/datasets/acme-vision?limit=10&includeSamples=false"Respuesta:
{
"datasets": [
{
"id": "65f1c0a2b3d4e5f601234567",
"owner": "acme-vision",
"dataset": "warehouse",
"name": "Warehouse",
"task": "detect",
"visibility": "private",
"imageCount": 1000,
"classCount": 2,
"classNames": ["person", "forklift"],
"splits": { "train": 800, "val": 200, "test": 0, "labeled": 1000 },
"annotationCount": 5400,
"starCount": 3,
"isStarred": false,
"status": "ready",
"createdAt": "2026-01-15T10:00:00Z",
"updatedAt": "2026-01-16T08:30:00Z"
}
],
"total": 1,
"region": "us"
}Obtener conjunto de datos#
GET /api/datasets/{owner}/{dataset}SDK de Python: client.datasets.retrieve(owner, dataset)
Devuelve el objeto completo del conjunto de datos bajo una clave dataset, que incluye classNames, splits, versions, source y el objeto metadata definido por el usuario. Mientras se procesa una importación de 10 000 imágenes o más, los editores también reciben processingProgress con stage, percent y, cuando se conocen, processed, total y objects (objetos en la nube analizados).
Crear conjunto de datos#
POST /api/datasetsSDK de Python: client.datasets.create(dataset=..., name=...)
Cuerpo:
{
"dataset": "warehouse",
"name": "Warehouse",
"task": "detect",
"description": "Forklift and pedestrian safety dataset",
"classNames": ["person", "forklift"],
"visibility": "private",
"metadata": { "location": "factory-1", "reviewed": true },
"owner": "acme-vision"
}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
dataset | string | Sí | Nombre del conjunto de datos utilizado en las URL de la plataforma (en minúsculas, con guiones, máximo 128 caracteres) |
name | string | Sí | Nombre para mostrar (máximo 100 caracteres) |
description | string | No | Descripción (máximo 1000 caracteres) |
task | string | No | Tipo de tarea (predeterminado: detect) |
classNames | array | No | Nombres de clases en orden de índice (máximo 25.000); sin duplicados, sin distinguir mayúsculas de minúsculas en nombres de más de 2 caracteres |
format | string | No | Formato de anotación: yolo (predeterminado), coco, raw, ndjson |
visibility | string | No | public o private |
blurFaces | booleano | No | Desenfocar los rostros de las imágenes subidas al conjunto de datos (consulta Desenfoque de rostros) |
tags | array | No | Hasta 50 etiquetas de 50 caracteres cada una |
license | string | No | Identificador de licencia del conjunto de datos |
metadata | object | No | Metadatos JSON personalizados |
owner | string | No | Identificador del espacio de trabajo del equipo; de forma predeterminada, se usa tu espacio de trabajo personal |
Si ya existe en el espacio de trabajo un slug dataset, incluso en la papelera, se devuelve 409.
Valores task válidos al crear o actualizar un conjunto de datos: detect, segment, semantic, depth, classify, pose y obb. Los conjuntos de datos de profundidad no tienen clases.
Respuesta (201):
{
"id": "65f1c0a2b3d4e5f601234567",
"owner": "acme-vision",
"dataset": "warehouse",
"region": "us"
}Actualizar conjunto de datos#
PATCH /api/datasets/{owner}/{dataset}SDK de Python: client.datasets.update(owner, dataset)
Cuerpo (actualización parcial):
{
"name": "Warehouse Safety",
"description": "New description",
"visibility": "public",
"metadata": { "location": "factory-2", "reviewed": true }
}Campos aceptados: name, description, visibility, metadata, tags, classNames, classColors, format, task, license, iconColor, iconLetter, starred, blurFaces, kptSkeletonId (asigna una plantilla de esqueleto de pose a un conjunto de datos de poses) y initializeClassNames (la actualización devuelve 409, salvo que el conjunto de datos aún no tenga clases ni anotaciones). Envía un objeto metadata vacío ({}) para borrar los metadatos personalizados. Las claves de metadatos están limitadas a 128 caracteres y el objeto serializado, a 500 000 caracteres.
Respuesta:
{
"success": true,
"dataset": "warehouse-safety"
}Al cambiar el nombre, cambia el nombre de la URL; por tanto, usa el valor dataset devuelto en las solicitudes posteriores.
Eliminar conjunto de datos#
DELETE /api/datasets/{owner}/{dataset}SDK de Python: client.datasets.delete(owner, dataset)
Mueve el conjunto de datos a la papelera, donde se puede recuperar durante 30 días.
Clonar conjunto de datos#
POST /api/datasets/{owner}/{dataset}/cloneSDK de Python: client.datasets.clone(owner, dataset)
Copia un conjunto de datos accesible, con sus imágenes y etiquetas, en tu espacio de trabajo personal o en uno de equipo.
Cuerpo opcional (todos los campos son opcionales):
{
"dataset": "warehouse-copy",
"name": "Warehouse Copy",
"description": "Cloned for experimentation",
"visibility": "private",
"license": "CC-BY-4.0",
"owner": "acme-vision"
}Respuesta (201): id, owner, dataset, name, imageCount, classCount y region. Los conjuntos de datos respaldados por una fuente de almacenamiento conectada devuelven 409, porque sus archivos no se copian.
Descargar una exportación del conjunto de datos#
GET /api/datasets/{owner}/{dataset}/exportSDK de Python: client.datasets.export(owner, dataset)
Devuelve una URL de descarga NDJSON firmada. Omite v para exportar el estado actual del conjunto de datos y reutilizar la exportación almacenada en caché si no ha cambiado nada desde que se generó.
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
v | entero | Número de versión guardada (indexado desde 1). Omítelo para usar el conjunto de datos actual. |
Respuesta:
{
"downloadUrl": "https://storage.googleapis.com/...&signature=...",
"cached": true
}Al solicitar una versión específica, se devuelven downloadUrl y version en lugar de cached.
Crear versión del conjunto de datos#
POST /api/datasets/{owner}/{dataset}/exportSDK de Python: client.datasets.create_export(owner, dataset)
Crea una versión numerada e inmutable del conjunto de datos. Requiere acceso de editor. Establece download en false para guardar la versión sin preparar una descarga NDJSON; en ese caso, se omite downloadUrl. El SDK acepta download de ultralytics-platform>=0.1.73.
Cuerpo (opcional):
{
"description": "Added 500 training images",
"download": true
}Respuesta:
{
"version": 3,
"downloadUrl": "https://storage.googleapis.com/...&signature=...",
"reused": false
}reused es true cuando el conjunto de datos coincide con una versión existente, por ejemplo, justo después de restaurarlo. En ese caso, se devuelve esa versión y se actualiza su descripción si envías una.
Actualizar la descripción de la versión#
PATCH /api/datasets/{owner}/{dataset}/exportSDK de Python: client.datasets.update_export(owner, dataset, version=..., description=...)
Cuerpo:
{
"version": 2,
"description": "Fixed mislabeled classes"
}Respuesta: {"ok": true}
Restaurar versión del conjunto de datos#
POST /api/datasets/{owner}/{dataset}/restoreSDK de Python: client.datasets.restore(owner, dataset, version=...)
Recrea las imágenes, las anotaciones y las clases a partir de una versión guardada sin copiar los bytes de las imágenes.
Cuerpo:
{
"version": 2
}Respuesta: {"version": 2, "imageCount": 1000}
Comparar versiones del conjunto de datos#
GET /api/datasets/{owner}/{dataset}/versions/compare?base={from}&head={to}SDK de Python: client.datasets.compare(owner, dataset, base=1, head=2) (ultralytics-platform>=0.1.73)
| Parámetro | Tipo | Descripción |
|---|---|---|
base | int | Versión con la que se compara |
head | int | Versión con la que se compara |
cursor | string | nextCursor de la página anterior |
hash | string | hash de un elemento: devuelve esa imagen tal como la almacena cada versión, no los cambios |
Respuesta (resumida):
{
"summary": { "added": 0, "removed": 1, "modified": 1, "moved": 1, "labelsAdded": 1, "labelsRemoved": 2 },
"items": [
{
"hash": "b5c605c133f84c3024af7e652b135501",
"name": "000000000042",
"change": "moved",
"base": { "split": "val", "labelCount": 1 },
"head": { "split": "test", "labelCount": 1 }
}
]
}summary solo aparece en la primera página y contiene los totales exactos, además de un header que enumera las clases añadidas, eliminadas o renombradas y otros campos del conjunto de datos que difieren. El change de cada elemento es added, removed, modified (con el fields modificado) o moved (división modificada), y labelsRemoved incluye las etiquetas de las imágenes eliminadas. Si está presente, pasa nextCursor como cursor para obtener la página siguiente. Con hash, la respuesta es versions: la imagen tal como la almacena cada versión, con sus etiquetas y un imageUrl firmado. Cualquiera de los dos órdenes funciona; si intercambias base y head, una imagen eliminada se notifica como añadida. Las comparaciones usan el límite de velocidad predeterminado y las solicitudes sin hash también están limitadas a 10 por minuto por usuario y conjunto de datos, independientemente de la clave de API utilizada.
Obtener estadísticas del conjunto de datos#
GET /api/datasets/{owner}/{dataset}/class-statsSDK de Python: client.datasets.class_stats(owner, dataset)
Devuelve recuentos de anotaciones por clase, histogramas de imágenes y anotaciones, y mapas de calor. En los conjuntos de datos grandes se realiza un muestreo; en ese caso, sampleSize indica cuántas imágenes se han tenido en cuenta.
Respuesta (abreviada):
{
"classes": [{ "classId": 0, "count": 1500, "imageCount": 450 }],
"imageStats": {
"widthHistogram": [{ "bin": 640, "count": 120, "size": 1 }],
"heightHistogram": [{ "bin": 480, "count": 95, "size": 1 }],
"pointsHistogram": [{ "bin": 4, "count": 200, "size": 1 }],
"formatDistribution": { "jpg": 900, "png": 100 },
"fileSizeHistogram": [{ "bin": 250000, "count": 300, "size": 50000 }],
"objectsPerImageHistogram": [{ "bin": 5, "count": 210, "size": 1 }],
"bboxWidthHistogram": [{ "bin": 120, "count": 340, "size": 20 }],
"bboxHeightHistogram": [{ "bin": 90, "count": 300, "size": 20 }]
},
"locationHeatmap": {
"bins": [
[5, 10],
[8, 3]
],
"maxCount": 50
},
"dimensionHeatmap": {
"bins": [
[2, 5],
[3, 1]
],
"maxCount": 12,
"minWidth": 10,
"maxWidth": 1920,
"minHeight": 10,
"maxHeight": 1080
},
"classNames": ["person", "forklift"],
"cached": true,
"sampleSize": null
}Gestionar clases#
Combinar clases (reasignar las anotaciones a una clase de destino y, después, eliminar las clases de origen):
POST /api/datasets/{owner}/{dataset}/classes/mergeSDK de Python: client.datasets.merge_classes(owner, dataset, source_class_ids=..., target_class_id=...)
{
"sourceClassIds": [2, 4],
"targetClassId": 1
}Eliminar clases (se eliminan sus anotaciones y los ID de las clases restantes se desplazan hacia abajo):
POST /api/datasets/{owner}/{dataset}/classes/deleteSDK de Python: client.datasets.delete_classes(owner, dataset, class_ids=...)
{
"classIds": [2, 4]
}Ambas operaciones devuelven success, los valores actualizados de classNames y classColors, y un resumen de los cambios realizados (mergedClassIds y targetClassId, o deletedClassIds y deletedAnnotations).
Como los ID restantes se desplazan tras combinar o eliminar clases, estas operaciones no son idempotentes. Vuelve a obtener el conjunto de datos para consultar los índices de clase actuales antes de realizar otra operación con clases.
Redistribuir particiones#
POST /api/datasets/{owner}/{dataset}/splits/redistributeSDK de Python: client.datasets.redistribute_splits(owner, dataset, train=..., val=..., test=...)
Reasigna aleatoriamente las imágenes entre las particiones. Los tres porcentajes deben sumar 100.
{
"train": 80,
"val": 20,
"test": 0
}Respuesta: success, los recuentos resultantes de splits y modified (número de imágenes movidas).
Incrustaciones del conjunto de datos#
GET /api/datasets/{owner}/{dataset}/embeddings
POST /api/datasets/{owner}/{dataset}/embeddings
DELETE /api/datasets/{owner}/{dataset}/embeddingsSDK de Python: client.datasets.embeddings(owner, dataset), client.datasets.create_embeddings(owner, dataset), client.datasets.delete_embeddings(owner, dataset)
GET devuelve el resumen del análisis (analyzedAt, embeddingsCount, latestImageAt, activeJob). POST pone en cola un análisis de incrustaciones y devuelve 202 con un jobId. DELETE cancela el trabajo activo y devuelve el ID del trabajo cancelado o null.
Agrupación de imágenes#
GET /api/datasets/{owner}/{dataset}/images/clusteringSDK de Python: client.datasets.clustering(owner, dataset)
Devuelve la disposición UMAP 2D de un análisis completado, paginada mediante offset y limit (valor predeterminado y máximo: 50 000). Cada entrada contiene id, umapX, umapY, cluster, split, classIds, width, height, bytes, labelCount, labeled y missing. cluster es la isla visual del punto, ordenada por tamaño (0 = la más grande, -1 = dispersa), o null para diseños analizados antes de que se añadiera la agrupación.
Listar modelos entrenados con un conjunto de datos#
GET /api/datasets/{owner}/{dataset}/modelsSDK de Python: client.datasets.models(owner, dataset)
Respuesta:
{
"models": [
{
"id": "65f1c0a2b3d4e5f601234599",
"owner": "acme-vision",
"project": "inspection",
"model": "v3",
"name": "v3",
"status": "completed",
"task": "detect",
"epochs": 100,
"bestEpoch": 87,
"metrics": { "mAP50": 0.85, "mAP50-95": 0.72, "precision": 0.88, "recall": 0.81 },
"startedAt": "2026-01-14T22:00:00Z",
"completedAt": "2026-01-15T10:00:00Z",
"createdAt": "2026-01-14T21:55:00Z"
}
],
"count": 1
}Listar imágenes del conjunto de datos#
GET /api/datasets/{owner}/{dataset}/imagesSDK de Python: client.datasets.images(owner, dataset)
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
limit | int | Número máximo de imágenes que se devolverán (valor predeterminado: 50; máximo: 5000) |
offset | int | Número de imágenes que se omitirán (valor predeterminado: 0) |
cursor | string | ID de la última imagen de la página anterior, para la paginación mediante cursor |
includeTotal | booleano | Incluir el recuento total de coincidencias (valor predeterminado: true) |
split | string | Filtrar por partición: train, val, test |
hasLabel | booleano | Filtrar por estado de anotación |
hasError | booleano | Filtrar por estado de error de procesamiento |
classIds | string | ID de clase separados por comas; devuelve imágenes que contengan cualquiera de ellos |
search | string | Coincidencia de subcadena en el nombre del archivo, el nombre de la clase y los metadatos personalizados (máximo: 200 caracteres) |
q | string | Ordena por relevancia en lugar de sort: primero las coincidencias de texto y, después, hasta 1.000 resultados similares; un ID, hash o nombre de archivo actúa como search (máximo 200 caracteres) |
sort | string | newest (predeterminado), oldest, name-asc, name-desc, height-asc, height-desc, width-asc, width-desc, size-asc, size-desc, labels-asc, labels-desc |
includeThumbnails | booleano | Incluir URL firmadas de miniaturas (valor predeterminado: true) |
includeImageUrls | booleano | Incluir URL firmadas de imágenes a tamaño completo (valor predeterminado: false) |
includeLabels | booleano | Incluir anotaciones de vista previa limitadas (valor predeterminado: false) |
Respuesta:
{
"images": [
{
"id": "65f1c0a2b3d4e5f601234567",
"hash": "9f2c1d4b6a8e0f3c5d7b9a1e2f4c6d8b",
"ext": "jpg",
"name": "aisle-04",
"thumbnailUrl": "https://storage.googleapis.com/...&signature=...",
"width": 1920,
"height": 1080,
"split": "train",
"labelCount": 6,
"bytes": 284213,
"error": null
}
],
"total": 1000,
"hasMore": true,
"classes": ["person", "forklift"],
"errorCount": 0,
"nextCursor": "65f1c0a2b3d4e5f601234567"
}Obtener imágenes seleccionadas#
POST /api/datasets/{owner}/{dataset}/imagesSDK de Python: client.datasets.selected_images(owner, dataset, image_ids=...)
Devuelve la misma estructura de imagen para un máximo de 1000 ID de imagen proporcionados y acepta los mismos parámetros de consulta de filtro y URL que la operación de listado.
{
"imageIds": ["65f1c0a2b3d4e5f601234567", "65f1c0a2b3d4e5f601234568"]
}Copiar o mover imágenes#
POST /api/datasets/{owner}/{dataset}/images/adoptSDK de Python: client.datasets.adopt_images(owner, dataset, image_ids=..., release=...) (ultralytics-platform>=0.1.50)
Copia hasta 1000 imágenes de otros conjuntos de datos en este, igual que hace la aplicación con copiar y pegar, y devuelve el número adopted.
{
"imageIds": ["65f1c0a2b3d4e5f601234567"],
"release": false,
"classMapping": { "person": 0, "vase": null }
}Al establecer release o classMapping, se conservan las etiquetas y las particiones de los conjuntos de datos que puedes editar: release: false copia las imágenes y release: true las mueve fuera de su conjunto de datos de origen. Si omites ambos campos, se importan imágenes train sin etiquetas, al igual que al copiar desde un origen de solo lectura; mover desde un origen de solo lectura devuelve 403. Se omiten las imágenes existentes; al conservar las etiquetas y las particiones, se buscan duplicados dentro de la partición de destino. Las clases se asignan por nombre, sin distinguir mayúsculas de minúsculas para nombres de más de dos caracteres; 422 devuelve las clases de origen que no tienen coincidencia en unmatchedClasses, y classMapping asigna cada una a un índice de clase, un nombre de clase nuevo o null para descartar sus etiquetas. 409 significa que el destino es un conjunto de datos conectado, o que el origen o el destino está ocupado. Al conservar las etiquetas y las particiones, las tareas, los canales de imagen, los ajustes de pose o las escalas de profundidad incompatibles también devuelven 409, incluso para imágenes sin etiquetas.
Incorporar datos a un conjunto de datos#
POST /api/datasets/{owner}/{dataset}/ingestSDK de Python: client.datasets.ingest(owner, dataset, body=...)
Procesa una carga completada, un archivo remoto o un origen de almacenamiento conectado y lo incorpora a un conjunto de datos existente. Proporciona exactamente un origen:
| Campo | Tipo | Descripción |
|---|---|---|
sessionId | string | Sesión de carga de POST /api/upload/signed-url; la incorporación verifica y completa la carga si no se ha llamado a POST /api/upload/complete |
sourceUrl | string | URL HTTP o HTTPS pública de un archivo ZIP, TAR, TAR.GZ, TGZ o NDJSON (máximo: 4096 caracteres) |
reference | object | Un origen conectado: almacenamiento en la nube (provider: "cloud", integrationId, target, prefix) o local (provider: "local", keyId, root, prefix) |
targetSplit | string | train, val o test; sustituye la estructura de particiones del archivo |
conflictPolicy | string | skip, keep_both o replace para conflictos de nombre de archivo o de contenido |
classMapping | object | Asigna nombres de clase entrantes a un índice de clase, a un nombre de clase existente o nuevo, o a null para omitirlos |
imageMetadata | object | Metadatos personalizados identificados por la ruta de cada imagen relativa al archivo o por el valor NDJSON file |
Las sesiones de carga están asociadas a un conjunto de datos mediante assetId, que se pasa a POST /api/upload/signed-url; la incorporación rechaza las sesiones que pertenecen a otro conjunto de datos.
Cuerpo (archivo cargado):
{
"sessionId": "session_abc123",
"targetSplit": "train"
}Cuerpo (archivo remoto o NDJSON):
{
"sourceUrl": "https://example.com/my-dataset.zip"
}Cuerpo (importación de etiquetas en una incorporación posterior):
{
"sessionId": "session_abc123",
"classMapping": { "person": 0, "automobile": "forklift", "background": null }
}Cuerpo (asociación de metadatos por imagen):
{
"sessionId": "session_abc123",
"imageMetadata": {
"airbus-wing.jpg": { "aircraft": { "family": "A350" }, "inspectionStatus": "reviewed" },
"images/tail.jpg": { "aircraft": { "family": "A320" }, "inspectionSeverity": 2 }
}
}Las claves de metadatos deben coincidir con la ruta normalizada dentro del archivo, incluidas las carpetas. En las importaciones NDJSON, cada registro puede incluir su propio objeto metadata, que tiene prioridad sobre la entrada coincidente de imageMetadata. Las rutas de archivo están limitadas a 1024 caracteres, las claves de metadatos de nivel superior a 128 caracteres y cada objeto de metadatos —así como todo el mapa imageMetadata— a 500 000 caracteres serializados.
La primera ingesta crea automáticamente las clases del archivo. En las ingestas posteriores, las clases del archivo que se omitan en classMapping se comparan por nombre con las clases existentes del conjunto de datos, sin distinguir mayúsculas de minúsculas en nombres de más de dos caracteres; las clases sin coincidencia se añaden como clases nuevas. Las etiquetas solo se omiten para las clases asignadas explícitamente a null.
Respuesta (201):
{
"jobId": "65f1c0a2b3d4e5f6012345aa",
"status": "queued"
}Subir una imagen con metadatos usando Python
El mismo código sirve para un grupo de imágenes: añade más archivos al ZIP y las entradas correspondientes a imageMetadata.
import io
import zipfile
from pathlib import Path
import requests
api = "https://platform.ultralytics.com/api"
headers = {"Authorization": "Bearer YOUR_API_KEY"}
owner, dataset = "acme-vision", "warehouse"
dataset_id = "65f1c0a2b3d4e5f601234567" # id returned by POST /api/datasets
image_path = Path("airbus-wing.jpg")
archive = io.BytesIO()
with zipfile.ZipFile(archive, "w", zipfile.ZIP_DEFLATED) as zf:
zf.write(image_path, image_path.name)
data = archive.getvalue()
signed = requests.post(
f"{api}/upload/signed-url",
headers=headers,
json={
"assetType": "datasets",
"assetId": dataset_id,
"filename": "images.zip",
"contentType": "application/zip",
"totalBytes": len(data),
},
)
signed.raise_for_status()
upload = signed.json()
headers_put = {"Content-Type": "application/zip", **upload.get("headers", {})}
requests.put(upload["uploadUrl"], headers=headers_put, data=data).raise_for_status()
requests.post(
f"{api}/upload/complete",
headers=headers,
json={"sessionId": upload["sessionId"]},
).raise_for_status()
ingest = requests.post(
f"{api}/datasets/{owner}/{dataset}/ingest",
headers=headers,
json={
"sessionId": upload["sessionId"],
"imageMetadata": {
"airbus-wing.jpg": {
"aircraft": {"family": "A350", "section": "wing"},
"inspectionStatus": "reviewed",
}
},
},
)
ingest.raise_for_status()
print(ingest.json())API de imágenes#
Inspecciona, anota, mueve y elimina imágenes del conjunto de datos mediante su ID de imagen de 24 caracteres. Consulta la documentación sobre anotaciones.
Obtener imagen#
GET /api/images/{imageId}SDK de Python: client.images.retrieve(image_id)
Devuelve metadata (personalizados, definidos por el usuario), properties (nombre de archivo, hash, dimensiones, partición, recuentos y marcas de tiempo), labels y classNames del conjunto de datos.
Actualizar imagen#
PATCH /api/images/{imageId}SDK de Python: client.images.update(image_id, body=...)
Sustituye las anotaciones o los metadatos personalizados; envía una de las dos estructuras, no ambas.
Cuerpo (anotaciones):
{
"labels": [
{ "classId": 0, "bbox": [0.5, 0.5, 0.2, 0.3] },
{ "classId": 1, "segments": [0.1, 0.2, 0.3, 0.2, 0.2, 0.4] }
]
}Cuerpo (metadatos):
{
"metadata": { "location": "strasbourg", "reviewed": true }
}Las coordenadas de las etiquetas usan valores normalizados de YOLO entre 0 y 1. Las cajas delimitadoras usan [x_center, y_center, width, height]. Las etiquetas de segmentación usan segments, una lista aplanada de vértices de polígonos [x1, y1, x2, y2, ...]. Las etiquetas de pose usan keypoints con una estructura plana coherente: pares [x1, y1, x2, y2, ...] o tríos [x1, y1, v1, x2, y2, v2, ...], donde la visibilidad suele usar 0, 1 o 2. Las cajas orientadas usan las esquinas obb. Las coordenadas guardadas se redondean a 5 decimales y una imagen admite un máximo de 10 000 anotaciones.
Eliminar imagen#
DELETE /api/images/{imageId}SDK de Python: client.images.delete(image_id)
Elimina permanentemente una imagen y sus anotaciones.
Anotar imagen automáticamente#
POST /api/images/{imageId}/predictSDK de Python: client.images.predict(image_id, model_id=...)
Ejecuta el modelo en la imagen y devuelve las anotaciones predichas. No las guarda: escribe los resultados con PATCH /api/images/{imageId} cuando te convenzan.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
modelId | string | Sí | URI de modelo completa, ul://{owner}/{project}/{model} o ID de modelo con indicaciones de clase para un conjunto de datos de detección con entre 1 y 200 clases: un modelo alojado (qwen, moondream, florence2, owlv2, yoloe26x, sam3, sam3.1, groundingdino) o un ID de modelo de proveedor de pago del enum modelId en openapi.json |
confidence | float | No | Umbral de confianza, 0.01–1.0 (valor predeterminado: 0.25); se ignora en los modelos con indicaciones de clase, que usan umbrales específicos del modelo |
iou | float | No | Umbral de IoU para la supresión no máxima, 0.0–0.95 (valor predeterminado: 0.7); se ignora en los modelos con indicaciones de clase |
classMapping | array | No | Para un modelo YOLO, el índice de clase del conjunto de datos correspondiente a cada clase del modelo, en orden, o null para descartar esa clase; si la longitud no es correcta o un índice queda fuera de las clases del conjunto de datos, se devuelve 400. Se ignora en los modelos con indicaciones de clase |
Respuesta: success, predictions (objetos de anotación), confidences (puntuaciones alineadas por índice, vacío para modelos con indicaciones de clase), modelUsed, inferenceTime; para modelos con indicaciones de clase, partial (true cuando la salida truncada de un modelo generativo solo devolvió las cajas completas); y, para modelos de proveedores de pago, un cost opcional (coste estimado del proveedor en USD, facturado a tu clave de proveedor; se omite si no hay ninguna estimación disponible). Un modelo YOLO cuyas clases no coincidan con el conjunto de datos devuelve 422, al igual que un modelo con indicaciones de clase en un conjunto de datos que no sea de detección o que tenga menos de 1 o más de 200 clases, y un modelo de proveedor de pago si no se ha guardado ninguna clave de proveedor en Settings > API Keys del espacio de trabajo del conjunto de datos (code: missing_provider_api_key). Los errores del proveedor incluyen su mensaje: 422 cuando el proveedor responde con 400, 401, 403 o 404 (clave, modelo o solicitud rechazados); 429 si se alcanza el límite de solicitudes; y 503 para cualquier otro error del proveedor. Los conjuntos de datos de profundidad devuelven 400, y los conjuntos de datos en almacenamiento conectado o con más de 3 canales de imagen devuelven 409.
Buscar imágenes similares#
GET /api/images/{imageId}/similarSDK de Python: client.images.find_similar_images(image_id)
Devuelve hasta 24 images visualmente similares de conjuntos de datos públicos y de tus propios conjuntos de datos y los de tu equipo, cada una con score (0-1), un thumbnailUrl firmado y el dataset de origen (owner, dataset, license). Se excluyen las imágenes que ya están en el conjunto de datos de origen y las copias de la imagen de consulta. Requiere una clave de API con acceso de visualización a la imagen; las imágenes que aún no se hayan incrustado se incrustan primero, y 503 indica que ha fallado el proceso, por lo que debes volver a intentarlo.
Anotar automáticamente un conjunto de datos#
POST /api/datasets/{owner}/{dataset}/predict/batchSDK de Python: client.datasets.create_batch(owner, dataset, body={...}) (ultralytics-platform>=0.1.57)
Guarda una versión del conjunto de datos y, después, pone en cola una ejecución que etiqueta las imágenes sin etiquetar del conjunto de datos con el modelo y devuelve 202. El cuerpo admite los mismos campos modelId, confidence, iou y classMapping que el endpoint para una sola imagen, además de includeAnnotated (valor predeterminado: false) para anotar también las imágenes que ya tienen etiquetas. Un modelo con indicaciones de clase detecta las clases del conjunto de datos sin puntuaciones de confianza, y un modelo de proveedor de pago necesita una clave de proveedor guardada en el espacio de trabajo del conjunto de datos, en Settings > API Keys (422, code: missing_provider_api_key, antes de admitir la ejecución). Las etiquetas existentes nunca se modifican y la ejecución se factura por las imágenes que realmente procesa. 402 indica que el saldo no cubre el importe estimado; 409, que el conjunto de datos no está listo, no tiene imágenes pendientes de anotación o ya tiene una ejecución en curso; y 422, que el conjunto de datos no tiene clases o que se ha proporcionado un conjunto de datos que no es de detección o que tiene menos de 1 o más de 200 clases a un modelo con indicaciones de clase: crea las clases con el endpoint de clases antes de llamar a este endpoint, tal como hace la aplicación en el paso Asignar clases antes de iniciar una ejecución.
GET en la misma ruta (client.datasets.batch(owner, dataset)) devuelve la ejecución en curso y su progreso, o la última ejecución completada hasta que se descarte, cuyos valores de results incluyen partialImages cuando la ejecución de un modelo generativo conservó únicamente las cajas completas de la salida truncada; DELETE (client.datasets.delete_batch(owner, dataset)) cancela una ejecución en curso o liquida la facturación y descarta el resumen de una ejecución completada.
El mismo endpoint desenfoca rostros con "operation": "blur", confidence (valor predeterminado: 0.25) y boxScale (0.5–1.5, valor predeterminado: 1); imageId limita la ejecución a una imagen. No crea ninguna versión ni modifica las etiquetas. Envía "preview": true para procesar hasta seis imágenes sin modificarlas; después, envía el valor jobId que se devuelva como previewJobId con la misma configuración para aplicar los cambios; una vista previa aplicada no se puede volver a usar y devuelve 409. Mientras haya una vista previa pendiente, pasa su ID como previewJobId a DELETE para descartarla.
{ "operation": "blur", "confidence": 0.25, "boxScale": 1, "preview": true }Mover imágenes en bloque#
PATCH /api/images/bulkSDK de Python: client.images.update_bulk(image_ids=..., split=...)
Mueve hasta 1000 imágenes de un conjunto de datos a otra partición.
{
"imageIds": ["65f1c0a2b3d4e5f601234567"],
"split": "val",
"conflictPolicy": "skip"
}Los conflictos de nombre de archivo o de contenido devuelven 409 hasta que elijas una opción para todo el lote: conflictPolicy de skip, keep_both o replace. La respuesta indica modifiedCount, skippedCount y targetSplit.
Eliminar imágenes en bloque#
DELETE /api/images/bulkSDK de Python: client.images.delete_bulk(image_ids=...)
{
"imageIds": ["65f1c0a2b3d4e5f601234567", "65f1c0a2b3d4e5f601234568"]
}Elimina hasta 1000 imágenes de un único conjunto de datos y devuelve deletedCount y deletedImageIds.
Obtener URL firmadas de imágenes#
POST /api/images/urlsSDK de Python: client.images.urls(image_ids=...)
Devuelve URL firmadas temporales para un máximo de 100 ID de imagen de un conjunto de datos.
{
"imageIds": ["65f1c0a2b3d4e5f601234567"]
}Respuesta: urls, thumbnails y depths (vistas previas del objetivo de profundidad para imágenes de profundidad emparejadas), todos organizados por ID de imagen.
API de proyectos#
Organiza tus modelos en proyectos. Cada modelo pertenece a un proyecto. Consulta la documentación sobre proyectos.
Listar proyectos#
GET /api/projects/{owner}SDK de Python: client.projects.list(owner)
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
limit | int | Número máximo de proyectos que se devolverán (valor predeterminado: 20; máximo: 500) |
Obtener proyecto#
GET /api/projects/{owner}/{project}SDK de Python: client.projects.retrieve(owner, project)
Devuelve el objeto project, una matriz models con resúmenes por modelo (estado, métricas, épocas, pesos y argumentos de entrenamiento), y isOwner. Pasa search (máximo: 200 caracteres) para filtrar models por nombre o metadatos del modelo.
Crear un proyecto#
POST /api/projectsSDK de Python: client.projects.create(project=..., name=...)
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
project | string | Sí | Nombre del proyecto utilizado en las URL de Platform |
name | string | Sí | Nombre para mostrar (máximo 100 caracteres) |
description | string | No | Descripción (máximo 1000 caracteres) |
visibility | string | No | public o private |
tags | array | No | Hasta 50 etiquetas |
license | string | No | Identificador de licencia del proyecto |
metadata | object | No | Metadatos JSON personalizados |
owner | string | No | Identificador del espacio de trabajo del equipo; de forma predeterminada, se usa tu espacio de trabajo personal |
curl -X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"project": "inspection",
"name": "Inspection",
"description": "Detection experiments",
"metadata": {"department": "manufacturing", "cost_center": "cv-01"}
}' \
https://platform.ultralytics.com/api/projectsRespuesta (201): id, owner, project, region.
Si ya existe en el espacio de trabajo un slug project, incluso en la papelera, se devuelve 409.
Actualizar proyecto#
PATCH /api/projects/{owner}/{project}SDK de Python: client.projects.update(owner, project)
Campos aceptados: name, description, visibility, metadata, tags, license, archived, iconColor, iconLetter, viewPreferences y starred.
{
"metadata": { "department": "research", "program": "inspection" }
}Envía un objeto metadata vacío ({}) para borrarlo. Los metadatos del proyecto tienen los mismos límites de 128 caracteres por clave y 500 000 caracteres por objeto serializado que los metadatos del conjunto de datos.
Eliminar proyecto#
DELETE /api/projects/{owner}/{project}SDK de Python: client.projects.delete(owner, project)
Mueve el proyecto y sus modelos a la papelera, devuelve cascadedModels y elimina permanentemente sus implementaciones. Restaurar el proyecto no restaura las implementaciones. 502 significa que la limpieza de las implementaciones no ha terminado; los modelos permanecen en la papelera hasta que se complete.
Clonar un proyecto#
POST /api/projects/{owner}/{project}/cloneSDK de Python: client.projects.clone(owner, project)
Clona un proyecto accesible y sus modelos completados. El cuerpo opcional acepta project, name, description, visibility, license y un destino owner.
API de modelos#
Gestiona modelos YOLO entrenados: consulta métricas, descarga pesos, ejecuta inferencias y supervisa el entrenamiento. Consulta la documentación de modelos.
Listar modelos de un proyecto#
GET /api/models/{owner}/{project}SDK de Python: client.models.list(owner, project)
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
limit | int | Número máximo de modelos que se devolverán (predeterminado: 20, máximo: 100) |
Obtener modelo#
GET /api/models/{owner}/{project}/{model}SDK de Python: client.models.retrieve(owner, project, model)
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
analysis | int | Establécelo en 1 para devolver el análisis de validación por imagen en lugar del modelo |
La respuesta predeterminada contiene el objeto model: estado, tarea, métricas, trainArgs, trainResults, classNames, computeCost, metadata y más; además de isOwner.
Crear modelo#
POST /api/modelsSDK de Python: client.models.create(body=...)
Crea un registro de modelo sin entrenar al que puedes asociar pesos o que puedes entrenar.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
project | string | Sí | Nombre del proyecto de destino |
owner | string | No | Identificador del espacio de trabajo; de forma predeterminada, se usa tu espacio de trabajo personal |
model | string | No | Nombre del modelo que se usa en las URL de Platform; se genera si se omite |
name | string | No | Nombre para mostrar (solo se acepta junto con model) |
description | string | No | Descripción (máximo 1000 caracteres) |
task | string | No | detect, segment, semantic, depth, classify, pose o obb |
metadata | object | No | Metadatos JSON personalizados |
trainArgs | object | No | Argumentos de entrenamiento que se registrarán |
metrics | object | No | Métricas como mAP50, mAP50-95, precision, recall |
epochs | número | No | Número de épocas de un modelo ya entrenado |
version | string | No | Etiqueta de versión (máx. 50 caracteres) |
Respuesta (201): id, owner, project, model, region.
Para adjuntar pesos .pt, solicita una URL de subida firmada con assetType: "models" y el id de este modelo como assetId, PUT el archivo a la URL devuelta y, después, llama a POST /api/upload/complete con el sessionId devuelto.
Actualizar modelo#
PATCH /api/models/{owner}/{project}/{model}SDK de Python: client.models.update(owner, project, model)
Entre los campos aceptados se incluyen name, description, color, metadata, status, license, datasetSlug, trainArgs, trainResults, epochs, bestEpoch, bestFitness, version, trainingError y starred. Si pasas projectId por sí solo, moverás el modelo a otro proyecto del mismo propietario; la respuesta devuelve slug del modelo en el proyecto de destino, renamed: true si ese slug ya está en uso allí y 409 mientras el modelo siga entrenándose.
{
"metadata": { "release": "candidate-3", "reviewed": true }
}metadata personalizado es independiente de los campos controlados por el entrenamiento, como trainArgs, environment y trainResults, y usa los mismos límites de tamaño que los metadatos del conjunto de datos.
Eliminar modelo#
DELETE /api/models/{owner}/{project}/{model}SDK de Python: client.models.delete(owner, project, model)
Mueve el modelo a la papelera durante 30 días y elimina permanentemente todas las implementaciones que lo usan, incluidas las sustituciones pendientes. Restaurar el modelo no restaura las implementaciones.
Descargar archivos del modelo#
GET /api/models/{owner}/{project}/{model}/filesSDK de Python: client.models.files(owner, project, model)
Devuelve URL firmadas de corta duración para los pesos del modelo.
{
"files": [
{
"name": "best.pt",
"size": 6534127,
"downloadUrl": "https://storage.googleapis.com/...&signature=..."
}
]
}Buscar imágenes similares a las peores imágenes de validación#
GET /api/models/{owner}/{project}/{model}/similar-imagesSDK de Python: client.models.find_similar_training_images(owner, project, model)
Devuelve hasta 100 images, con el mismo formato que Buscar imágenes similares, que se parecen a las imágenes de validación con peores resultados en esta ejecución de entrenamiento, excluyendo las imágenes que ya contiene el conjunto de datos de entrenamiento. Pasa hashes (separados por comas, hasta 100) para buscar a partir de un subconjunto de esas imágenes con peores resultados. Requiere una clave de API con acceso al espacio de trabajo del modelo. La lista está vacía si la ejecución no registró resultados por imagen; 404 también significa que las peores imágenes aún no están integradas: ejecuta primero las incrustaciones del conjunto de datos en el conjunto de datos de entrenamiento.
Clonar modelo#
POST /api/models/{owner}/{project}/{model}/cloneSDK de Python: client.models.clone(owner, project, model, project_body=...)
Copia un modelo accesible en un proyecto existente.
{
"owner": "acme-vision",
"project": "inspection",
"model": "v3-copy",
"name": "V3 Copy",
"description": "Cloned from a public model"
}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
project | string | Sí | Nombre del proyecto de destino |
owner | string | No | Espacio de trabajo de destino; de forma predeterminada, se usa el tuyo personal |
model | string | No | Nombre del modelo de destino |
name | string | No | Nombre para mostrar del destino |
description | string | No | Descripción del clon |
Ejecuta la inferencia#
POST /api/models/{owner}/{project}/{model}/predictSDK de Python: client.models.predict(owner, project, model, body=...)
Se pueden obtener predicciones de modelos públicos sin autenticación. Los modelos privados y compartidos requieren una clave de API con acceso al proyecto principal.
Formulario multiparte:
| Parámetro | Tipo | Predeterminado | Intervalo | Descripción |
|---|---|---|---|---|
file | file | - | - | Archivo de imagen o vídeo (obligatorio, salvo que se haya definido source) |
conf | float | 0.25 | 0.01 – 1.0 | Umbral mínimo de confianza |
iou | float | 0.7 | 0.0 – 0.95 | Umbral de IoU de NMS |
imgsz | int | - | 32 – 1280 | Tamaño de la imagen de entrada en píxeles; de forma predeterminada, se utiliza el tamaño de entrenamiento del modelo (640 si no está disponible) |
normalize | bool | false | - | Devuelve las coordenadas de las cajas delimitadoras en el intervalo 0 – 1 |
decimals | int | 5 | 0 – 10 | Precisión decimal de los valores de las coordenadas |
vid_stride | int | 1 | ≥ 1 | Predice cada N fotogramas del vídeo; se ignora en las imágenes |
bits | int | 8 | 8, 12, 16 | Cuantización del mapa de profundidad; solo para modelos de profundidad |
source | string | - | - | URL de imagen o cadena en base64 (alternativa a file); máximo de 4,096 caracteres mediante la API de Platform |
Proporciona file o source. Los modelos de profundidad también aceptan bits (8, 12 o 16) para seleccionar la cuantización PNG del mapa de profundidad. Las solicitudes que superen los límites de entrada del servicio devuelven 413.
curl -X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@image.jpg" \
-F "conf=0.5" \
https://platform.ultralytics.com/api/models/acme-vision/inspection/v3/predictRespuesta:
Cada entrada de images incluye shape, speed, results y, para tareas de predicción densa, una carga útil PNG semantic_mask o depth (los valores de profundidad son pixel × max / divisor, con divisor 255 para el mapa predeterminado de 8 bits y 65535 cuando bits es 12 o 16). El objeto metadata informa del número de imágenes, los nombres de las clases del modelo, los tiempos de las funciones, la tarea y las versiones del servicio. Nunca se devuelven las rutas internas del modelo.
{
"images": [
{
"shape": [1080, 1920],
"speed": { "preprocess": 2.1, "inference": 12.4, "postprocess": 1.3 },
"results": [
{
"class": 0,
"name": "person",
"confidence": 0.92,
"box": { "x1": 100, "y1": 50, "x2": 300, "y2": 400 }
}
]
}
],
"metadata": {
"imageCount": 1,
"classNames": ["person", "forklift"],
"functionTimeAlive": 184.2,
"functionTimeCall": 0.31,
"task": "detect",
"version": { "ultralytics": "8.4.120" }
}
}Comprobar el progreso del entrenamiento#
GET /api/models/{owner}/{project}/{model}/trainingSDK de Python: client.models.training(owner, project, model)
Devuelve job, que contiene el estado, el progreso de las épocas, los tiempos, los detalles del cálculo, los argumentos de entrenamiento, las métricas por época y los detalles de error seguros, o null si el modelo nunca se ha entrenado. Los modelos de proyectos públicos se pueden consultar sin autenticación.
Cancelar el entrenamiento#
DELETE /api/models/{owner}/{project}/{model}/trainingSDK de Python: client.models.delete_training(owner, project, model)
Termina la instancia de cálculo en ejecución y marca el trabajo como cancelado. Devuelve 409 si el entrenamiento ya no está activo.
API de entrenamiento#
Inicia el entrenamiento de YOLO en GPU en la nube y supervisa el progreso en tiempo real. Consulta la documentación de entrenamiento en la nube.
Consultar la disponibilidad de GPU#
GET /api/training/gpu-availabilitySDK de Python: client.training.gpu_availability()
Devuelve el estado actual de disponibilidad organizado por ID de GPU. Es público y no requiere autenticación; pasa managed=true para incluir la capacidad de entrenamiento gestionada, que sí requiere una clave de API.
Iniciar entrenamiento#
POST /api/training/startSDK de Python: client.training.start(model_id=..., train_args=...)
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
modelId | string | Sí | ID del modelo que se va a entrenar |
trainArgs | object | Sí | Argumentos de entrenamiento de YOLO; se requieren model, data y epochs |
gpuType | string | No | GPU en la nube que se usará (predeterminada: rtx-4090) |
captureDatasetVersion | booleano | No | Guarda una versión inmutable del conjunto de datos para esta ejecución (predeterminado: false) |
curl -X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"modelId": "65f1c0a2b3d4e5f601234599",
"gpuType": "rtx-4090",
"trainArgs": {
"model": "yolo26n.pt",
"data": "ul://acme-vision/datasets/warehouse",
"epochs": 100,
"imgsz": 640,
"batch": 16
}
}' \
https://platform.ultralytics.com/api/training/startRespuesta:
{
"modelId": "65f1c0a2b3d4e5f601234599",
"status": "starting",
"gpuType": "rtx-4090",
"estimatedCost": { "pricePerHour": 0.69, "gpuMemoryGb": 24 },
"billing": {
"estimatedCostCents": 138,
"estimatedCostDisplay": "$1.38",
"balanceCents": 2500
}
}El entrenamiento devuelve 402 si tu saldo de crédito es demasiado bajo y 503 si no hay capacidad disponible para la GPU solicitada.
Hay 26 tipos de GPU disponibles, desde rtx-2000-ada hasta b300, incluidos rtx-4090, l40s, a100-80gb-pcie, a100-80gb-sxm, rtx-pro-6000, h100-sxm, h200-sxm y b200. Consulta Entrenamiento en la nube para ver la lista completa con precios.
API de exportaciones#
Convierte modelos a formatos optimizados como ONNX, TensorRT, CoreML y LiteRT para su implementación en dispositivos periféricos. Consulta la documentación de implementación.
Listar exportaciones#
GET /api/models/{owner}/{project}/{model}/exportsSDK de Python: client.exports.list(owner, project, model)
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
status | string | Filtrar por queued, starting, running, completed, failed o cancelled |
limit | int | Número máximo de exportaciones que se devolverán (predeterminado: 20, máximo: 100) |
Crear exportación#
POST /api/models/{owner}/{project}/{model}/exportsSDK de Python: client.exports.create(owner, project, model, format=...)
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
format | string | Sí | Formato de exportación de destino (consulta la tabla siguiente) |
gpuType | string | Condicional | Obligatorio cuando format es engine; usa un destino de GPU o Jetson compatible |
args | object | No | Opciones de exportación: imgsz, quantize, dynamic, simplify, opset, conf, iou, batch, workspace, nms, optimize y name (dispositivo de destino para RKNN, QNN, Hailo, Ascend y Xilinx) |
curl -X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"format": "onnx", "args": {"imgsz": 640, "quantize": 16}}' \
https://platform.ultralytics.com/api/models/acme-vision/inspection/v3/exportsCada formato solo admite las opciones de la columna Argumentos de la tabla de exportación siguiente: si se especifica un valor no predeterminado de batch, dynamic, opset, simplify, workspace o optimize para un formato que no lo admite, se devuelve 400. Las exportaciones imx son solo INT8 y están disponibles para modelos de detección, segmentación, clasificación y pose; los modelos YOLO26 y los tamaños de YOLOv8 o YOLO11 distintos de nano devuelven 400.
Respuesta (201): id, format, status (queued o running), region y gpuType para exportaciones TensorRT. Una exportación equivalente que ya esté en curso devuelve 409.
Formatos compatibles:
Usa el argumento format de la tabla de exportación común que aparece a continuación. PyTorch es el formato de origen y no es un destino de exportación de la API.
| Formato | Argumento format | Modelo | Metadatos | Argumentos |
|---|---|---|---|---|
| PyTorch | - | yolo26n.pt | ✅ | - |
| TorchScript | torchscript | yolo26n.torchscript | ✅ | imgsz, quantize, dynamic, nms, batch, device |
| ONNX | onnx | yolo26n.onnx | ✅ | imgsz, quantize, dynamic, simplify, opset, nms, batch, data, fraction, device |
| OpenVINO | openvino | yolo26n_openvino_model/ | ✅ | imgsz, quantize, dynamic, nms, batch, data, fraction, device |
| TensorRT | engine | yolo26n.engine | ✅ | imgsz, quantize, dynamic, simplify, opset, workspace, nms, batch, data, fraction, device |
| CoreML | coreml | yolo26n.mlpackage | ✅ | imgsz, dynamic, quantize, nms, batch, device |
| Apple Core AI | coreai | yolo26n.aimodel | ✅ | imgsz, batch, quantize |
| TF SavedModel | saved_model | yolo26n_saved_model/ | ✅ | imgsz, quantize, opset, nms, batch, data, fraction, device |
| TF GraphDef | pb | yolo26n.pb | ❌ | imgsz, opset, batch, device |
| TF Edge TPU | edgetpu | yolo26n_edgetpu.tflite | ✅ | imgsz, quantize, opset, data, fraction, device |
| LiteRT | litert | yolo26n.tflite | ✅ | imgsz, quantize, batch, data, fraction, device |
| PaddlePaddle | paddle | yolo26n_paddle_model/ | ✅ | imgsz, batch, device |
| MNN | mnn | yolo26n.mnn | ✅ | imgsz, batch, dynamic, quantize, simplify, opset, nms, device |
| NCNN | ncnn | yolo26n_ncnn_model/ | ✅ | imgsz, quantize, batch, device |
| IMX500 | imx | yolo26n_imx_model/ | ✅ | imgsz, quantize, data, fraction, nms, device |
| RKNN | rknn | yolo26n_rknn_model/ | ✅ | imgsz, batch, name, quantize, simplify, opset, data, fraction, device |
| ExecuTorch | executorch | yolo26n_executorch_model/ | ✅ | imgsz, batch, device |
| Axelera | axelera | yolo26n_axelera_model/ | ✅ | imgsz, batch, quantize, data, fraction, device |
| DEEPX | deepx | yolo26n_deepx_model/ | ✅ | imgsz, quantize, simplify, opset, data, optimize, device |
| Qualcomm QNN | qnn | yolo26n_qnn.onnx | ✅ | imgsz, batch, name, quantize, simplify, opset, data, fraction, device |
| Hailo | hailo | yolo26n_hailo_model/ | ✅ | imgsz, name, quantize, data, fraction, simplify, conf, iou, device |
| Huawei Ascend | ascend | yolo26n_ascend_model/ | ✅ | imgsz, batch, name, quantize, opset, simplify, nms, device |
| AMD Xilinx | xilinx | yolo26n_xilinx_model/ | ✅ | imgsz, name, quantize, data, fraction, opset, simplify, device |
nms=None usa de forma predeterminada salidas sin procesar para NMS externa. Establece nms=False para seleccionar una cabeza sin NMS disponible; los formatos no compatibles recurren a su ruta de salida nativa. Las entradas nms anteriores identifican los formatos que pueden integrar NMS con nms=True.
Obtener el estado de la exportación#
GET /api/models/{owner}/{project}/{model}/exports/{exportId}SDK de Python: client.exports.retrieve(owner, project, model, export_id)
Devuelve el objeto export con status, format, args, gpuType (solo TensorRT), marcas de tiempo y, cuando se completa, un objeto file que contiene size, downloadUrl y downloadFilename.
Cancelar o eliminar exportación#
DELETE /api/models/{owner}/{project}/{model}/exports/{exportId}SDK de Python: client.exports.delete(owner, project, model, export_id)
Cancela una exportación activa o elimina una finalizada y su archivo. La respuesta indica cuál de las dos acciones se ha realizado:
{
"success": true,
"action": "cancelled"
}API de implementaciones#
Implementa modelos en puntos de inferencia dedicados con comprobaciones de estado y supervisión. Consulta la documentación de puntos de conexión.
Listar implementaciones#
GET /api/deployments/{owner}SDK de Python: client.deployments.list(owner)
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
status | string | creating, deploying, ready, stopping, stopped o failed |
model | string | Filtrar por {project}/{model}, por ejemplo, inspection/v3 |
limit | int | Número máximo de implementaciones que se devolverán (predeterminado: 20, máximo: 100) |
Los usuarios anónimos deben filtrar por un modelo público; para listar un espacio de trabajo completo es necesario autenticarse.
Crear implementación#
POST /api/deployments/{owner}SDK de Python: client.deployments.create(owner, project=..., model=..., deployment=..., name=..., region=...)
Cuerpo:
{
"project": "inspection",
"model": "v3",
"deployment": "edge-1",
"name": "Edge 1",
"region": "us-central1"
}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
project | string | Sí | Proyecto que contiene el modelo |
model | string | Sí | Modelo que se va a implementar |
deployment | string | Sí | Nombre de la implementación que se usa en las URL de Platform |
name | string | Sí | Nombre para mostrar |
region | string | Sí | Una de las 42 regiones de implementación compatibles |
cpu | número | No | Núcleos de vCPU: 1 (predeterminado), 2, 4, 6 u 8 |
memoryGi | número | No | Memoria en GiB: 2 (predeterminado), 4, 8, 16, 24 o 32 |
Respuesta (201): id, deployment, status (creating), message y region.
El tamaño predeterminado de 1 vCPU / 2 GiB se reduce a cero cuando está inactivo y puede beneficiarse de una asignación de implementaciones gratuitas; los demás tamaños usan precios según el consumo. Los valores actuales se devuelven en el objeto resources en cada consulta de implementación.
Elige una región cercana a tus usuarios para reducir al mínimo la latencia. La interfaz de Platform muestra estimaciones de latencia para las 42 regiones disponibles.
Obtener implementación#
GET /api/deployments/{owner}/{deployment}SDK de Python: client.deployments.retrieve(owner, deployment)
Devuelve el objeto deployment con status, statusMessage, region, serviceUrl, resources y metadata personalizados, además de camera y cameraApplying para el propietario.
Actualizar una implementación#
PATCH /api/deployments/{owner}/{deployment}SDK de Python: client.deployments.update(owner, deployment, body=...)
Envía uno de estos cuerpos:
{ "name": "Edge 1 (primary)" }Al cambiar el nombre, el valor deployment de la URL se establece como un slug del nuevo nombre, que se devuelve como deployment; la ruta anterior devuelve 404 y serviceUrl no cambia. Un objeto metadata vacío borra los metadatos personalizados. La sustitución implementa una nueva revisión y conserva el ID del despliegue, la región y la URL del endpoint; la revisión existente sigue activa si falla la implementación. El modelo de sustitución debe estar completado y tener pesos a los que pueda acceder tu clave. La acción de cámara guarda una cámara RTSP o RTSPS en la que un endpoint listo con recursos personalizados sigue ejecutando inferencias (consulta Cámara en segundo plano); "url": null la elimina, al igual que al volver a cambiar el tamaño al predeterminado, y guardar una cámara en un endpoint de tamaño predeterminado devuelve 403. Un cambio de cámara devuelve 202 con status ready mientras se aplica: consulta el despliegue hasta que cameraApplying deje de ser true y, después, comprueba camera; si falla el cambio, se conserva la cámara anterior y se establece statusMessage. Las operaciones completadas devuelven 200 con status ready o stopped; las demás operaciones que aún se estén implementando devuelven 202 con deploying o stopping.
Eliminar despliegue#
DELETE /api/deployments/{owner}/{deployment}SDK de Python: client.deployments.delete(owner, deployment)
Elimina permanentemente el endpoint de inferencia.
Comprobación del estado#
GET /api/deployments/{owner}/{deployment}/healthSDK de Python: client.deployments.health(owner, deployment)
Hace ping al endpoint y lo activa, y devuelve healthy, latencyMs y el código status del servicio ascendente.
Ejecutar inferencia en un despliegue#
POST /api/deployments/{owner}/{deployment}/predictSDK de Python: client.deployments.predict(owner, deployment, body=...)
Envía una imagen o un vídeo al endpoint dedicado. Los contratos de solicitud y respuesta coinciden con los de la inferencia de modelos. Las transmisiones de cámara no se redirigen; envíalas a la URL del endpoint tal como se describe en Inferencia con cámara en directo.
Formulario multiparte:
| Parámetro | Tipo | Predeterminado | Intervalo | Descripción |
|---|---|---|---|---|
file | file | - | - | Archivo de imagen o vídeo (obligatorio, salvo que se haya definido source) |
conf | float | 0.25 | 0.01 – 1.0 | Umbral mínimo de confianza |
iou | float | 0.7 | 0.0 – 0.95 | Umbral de IoU de NMS |
imgsz | int | - | 32 – 1280 | Tamaño de la imagen de entrada en píxeles; de forma predeterminada, se utiliza el tamaño de entrenamiento del modelo (640 si no está disponible) |
normalize | bool | false | - | Devuelve las coordenadas de las cajas delimitadoras en el intervalo 0 – 1 |
decimals | int | 5 | 0 – 10 | Precisión decimal de los valores de las coordenadas |
vid_stride | int | 1 | ≥ 1 | Predice cada N fotogramas del vídeo; se ignora en las imágenes |
bits | int | 8 | 8, 12, 16 | Cuantización del mapa de profundidad; solo para modelos de profundidad |
source | string | - | - | URL de imagen o cadena en base64 (alternativa a file); máximo de 4,096 caracteres mediante la API de Platform |
Obtener métricas#
GET /api/deployments/{owner}/{deployment}/metricsSDK de Python: client.deployments.metrics(owner, deployment)
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
range | string | 1h, 6h, 24h (predeterminado), 7d o 30d |
sparkline | booleano | Devuelve el resumen compacto del panel en lugar de la serie completa (predeterminado: false) |
view | string | overview devuelve solo las métricas de solicitudes, errores y latencia P95 |
La respuesta completa contiene summary (totales de solicitudes, tasa de errores, latencia media y p50/p95/p99) y timeSeries (solicitudes, errores, latencia, CPU, memoria y número de instancias). La respuesta de minigráficos devuelve requests24h (recuentos de solicitudes por hora; se omiten las horas sin solicitudes), totalRequests, errorRate y avgLatencyMs (la media de las latencias P95 por hora). Con view=overview, summary contiene totalRequests, errorRate, y p95LatencyMs, mientras que timeSeries contiene requests, errors y latencyP95.
Obtener registros#
GET /api/deployments/{owner}/{deployment}/logsSDK de Python: client.deployments.logs(owner, deployment)
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
severity | string | Separados por comas: DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY |
limit | int | Entradas que se devolverán (predeterminado: 50, máx.: 200) |
pageToken | string | Token de paginación de una respuesta anterior |
API de agentes#
Guarda y gestiona flujos de trabajo de agentes. La API almacena definiciones de agentes; las ejecuciones se inician desde el lienzo de Agents, donde https://platform.ultralytics.com/agents?workflow={id} abre un agente guardado. Los métodos del SDK de Python necesitan ultralytics-platform>=0.1.74.
Todas las operaciones aceptan un parámetro de consulta opcional owner con el nombre de usuario de un espacio de trabajo al que pertenezcas (predeterminado: el tuyo). Para listar se necesita acceso de visor; para guardar y eliminar, acceso de editor.
Listar agentes#
GET /api/workflowsSDK de Python: client.agents.list()
| Parámetro | Tipo | Descripción |
|---|---|---|
owner | string | Nombre de usuario del espacio de trabajo (predeterminado: el tuyo) |
id | string | Devuelve un agente con su graph |
search | string | Filtrar por nombre del agente |
La respuesta enumera hasta 100 agentes en workflows, ordenados del más reciente al más antiguo según su última actualización, cada uno con id, username, name, version, createdAt y updatedAt. Si solicitas un id, también se devuelve el graph del agente.
Guardar un agente#
PUT /api/workflowsSDK de Python: client.agents.save(name=..., graph=..., version=...)
Envía version: 0 para crear un agente. Para actualizar uno, envía su id y el version devuelto por la última operación de listado o guardado; si version está obsoleto, se devuelve 409, así que vuelve a listar el agente e inténtalo de nuevo. Si las conexiones de un grafo forman un ciclo o proporcionan más de una entrada a un bloque, se devuelve 400.
from ultralytics_platform import Platform
def block(node_id, kind, x, config):
return {
"id": node_id,
"type": "agent",
"position": {"x": x, "y": 0},
"data": {"label": kind, "type": kind, "config": config},
}
graph = {
"nodes": [
block("images", "Dataset", 0, {"dataset": "official:coco8", "split": "val", "maxInputs": 2}),
block("yolo", "YOLO", 220, {"model": "ul://ultralytics/yolo26/yolo26n", "task": "detect"}),
block("output", "Output", 440, {}),
],
"edges": [{"id": "e1", "source": "images", "target": "yolo"}, {"id": "e2", "source": "yolo", "target": "output"}],
"templateId": "",
}
with Platform() as client:
saved = client.agents.save(name="Detect COCO8", graph=graph, version=0)
print(saved["id"], saved["version"], saved["errors"])La respuesta devuelve el agente id, su nuevo version y errors: bloques que el lienzo señalaría, como un bloque Dataset sin ningún conjunto de datos seleccionado. El agente se guarda en cualquier caso. Consulta openapi.json para ver todos los tipos de bloque y su configuración.
Eliminar un agente#
DELETE /api/workflows?id={id}SDK de Python: client.agents.delete(id=...)
Elimina el agente y cancela sus ejecuciones activas. Los agentes eliminados no aparecen en la papelera y no se pueden restaurar.
API de la papelera#
Consulta, restaura y elimina permanentemente proyectos, conjuntos de datos y modelos eliminados de forma provisional. Los elementos se purgan automáticamente al cabo de 30 días. Consulta la documentación de la papelera.
Listar elementos de la papelera#
GET /api/trashSDK de Python: client.lifecycle.trash()
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
type | string | all (predeterminado), project, dataset o model |
page | int | Número de página (predeterminado: 1) |
limit | int | Elementos por página (predeterminado: 50, máx.: 200) |
id | string | Con type project o model, previsualiza los modelos y despliegues afectados por su eliminación |
La respuesta incluye items (cada uno con daysRemaining), total, page, limit, totalPages y un summary con los totales por tipo. Con id, en su lugar devuelve resources: los modelos afectados y los despliegues que se eliminarían permanentemente.
Restaurar elemento#
POST /api/trashSDK de Python: client.lifecycle.restore(id=..., type=...)
{
"id": "65f1c0a2b3d4e5f601234567",
"type": "dataset"
}Al restaurar un proyecto, también se restauran los modelos que se enviaron a la papelera con él, que se indican como restoredModels.
Eliminar permanentemente#
DELETE /api/trashSDK de Python: client.lifecycle.delete_trash(body=...)
Eliminar un elemento:
{
"id": "65f1c0a2b3d4e5f601234567",
"type": "dataset"
}O vaciar toda la papelera:
{
"all": true
}La respuesta indica deletedCount y, cuando corresponda, cascadedModels y survivingDeployments.
La eliminación permanente no se puede deshacer. Se eliminan el recurso y todos los datos asociados.
API de carga#
Sube archivos directamente al almacenamiento en la nube mediante URL firmadas. Al completar la carga de un modelo, se adjuntan sus pesos; al completar la carga de un archivo de conjunto de datos, se verifica y, a continuación, se pasa la sesión a la ingesta de conjuntos de datos, que también completa la carga si omites ese paso. Consulta la documentación de datos.
Obtener URL de carga firmada#
POST /api/upload/signed-urlSDK de Python: client.upload.signed_url(body=...)
Cuerpo:
{
"assetType": "datasets",
"assetId": "65f1c0a2b3d4e5f601234567",
"filename": "warehouse.zip",
"contentType": "application/zip",
"totalBytes": 52428800
}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
assetType | string | Sí | datasets o models |
assetId | string | Sí | ID del conjunto de datos o modelo de destino |
filename | string | Sí | Nombre de archivo original (máx. 256 caracteres) |
contentType | string | Sí | Tipo MIME |
totalBytes | número | Sí | Tamaño del archivo en bytes |
Cuando assetType es datasets, filename debe terminar en .zip, .tar, .tar.gz, .tgz o .ndjson. Empaqueta las imágenes sueltas en un archivo antes de subirlas.
Respuesta:
{
"sessionId": "session_abc123",
"uploadUrl": "https://storage.googleapis.com/...&signature=...",
"expiresAt": "2026-02-22T12:00:00Z",
"headers": { "x-goog-if-generation-match": "0" }
}Sube el archivo con una solicitud PUT a uploadUrl, usando el mismo Content-Type que declaraste y todas las cabeceras de headers. Las URL de carga de conjuntos de datos son válidas durante 12 horas y solo permiten crear archivos: una segunda solicitud PUT a la misma URL devuelve 412, y una solicitud PUT sin las cabeceras proporcionadas devuelve 400.
Completar carga#
POST /api/upload/completeSDK de Python: client.upload.complete(session_id=...)
{
"sessionId": "session_abc123",
"md5": "<optional md5 hex>"
}Respuesta: success y un objeto file con size y contentType. En el caso de los modelos, adjunta los pesos; en el de los archivos de conjuntos de datos, llama después a ingest para iniciar el procesamiento.
Si se proporciona md5, se comprueba con el objeto almacenado. Si no coincide, se devuelve 400; si la sesión aún no está completa, también se elimina el archivo subido y la sesión queda incompleta, así que solicita una nueva URL firmada y vuelve a subirlo. Se puede volver a completar una sesión de conjunto de datos completada mientras exista su archivo, pero si se intentan completar a la vez con resúmenes distintos, se devuelve 409; las sesiones de modelos se eliminan al completarlas. checksum se almacena como metadato del archivo del modelo y no se verifica.
API de integraciones de almacenamiento#
Conecta cuentas de Google Cloud Storage, Amazon S3 o Azure Blob Storage con acceso de solo lectura y explóralas como fuentes de conjuntos de datos. Consulta la documentación de integraciones.
Para descubrir y conectar almacenamiento se necesita acceso de administrador del espacio de trabajo y un plan Pro o Enterprise (403 en caso contrario); para listar integraciones y explorar objetos se necesita acceso de editor.
Listar integraciones#
GET /api/integrations/bucketsSDK de Python: client.storage_integrations.list()
Devuelve integrations, cada uno con id, provider, credentialIdentity, targets y createdAt. Las credenciales nunca se devuelven.
Descubrir ubicaciones#
POST /api/integrations/buckets/discoverSDK de Python: client.storage_integrations.discover(body=...)
Enumera los buckets o contenedores accesibles con las credenciales proporcionadas, sin guardarlas.
{
"provider": "gcs",
"credentials": {
"client_email": "svc@project.iam.gserviceaccount.com",
"private_key": "-----BEGIN PRIVATE KEY-----\n...",
"project_id": "my-project"
}
}Respuesta: {"targets": ["my-bucket", "another-bucket"]}
Conectar almacenamiento#
POST /api/integrations/bucketsSDK de Python: client.storage_integrations.create(body=...)
Los mismos formatos de credenciales que para el descubrimiento, más una matriz obligatoria targets con entre 1 y 50 nombres de bucket o contenedor. Devuelve 201 con la integración guardada. Se rechazan las credenciales temporales de S3 (claves de acceso ASIA).
Explorar objetos#
GET /api/integrations/buckets/{id}/objectsSDK de Python: client.storage_integrations.objects(id, target=...)
Parámetros de consulta:
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
target | string | Sí | Nombre del bucket o contenedor |
prefix | string | No | Prefijo de carpeta (máx. 1024 caracteres) |
cursor | string | No | Cursor de paginación del proveedor de una página anterior |
Devuelve entries (cada kind es folder o file) y un cursor opcional para la página siguiente.
Desconectar almacenamiento#
DELETE /api/integrations/buckets/{id}SDK de Python: client.storage_integrations.delete(id)
Elimina las credenciales guardadas sin borrar los datos del proveedor. Los conjuntos de datos conectados siguen visibles, pero sus archivos no estarán disponibles hasta que vuelvas a conectar la misma cuenta de almacenamiento. Se necesita acceso de administrador del espacio de trabajo.
API de importación de conjuntos de datos#
Importa conjuntos de datos desde servicios de terceros. Consulta la integración con Roboflow.
Previsualizar una importación de Roboflow#
POST /api/integrations/roboflow/previewSDK de Python: client.datasets.preview_roboflow(api_key=...)
Resuelve una clave de API de Roboflow en un plan de importación: detalles del espacio de trabajo, newDatasets que se importarían, recuentos de proyectos ya importados (skippedCount), sin versión, no compatibles y sin resolver, bytesTotal y el storage disponible en tu almacenamiento. La clave de API de Roboflow se lee del cuerpo de la solicitud y no se guarda.
{
"apiKey": "ROBOFLOW_API_KEY"
}Importar desde Roboflow#
POST /api/integrations/roboflow/importSDK de Python: client.datasets.import_roboflow(api_key=..., items=...)
Pone en cola trabajos de ingesta para hasta 500 versiones de proyectos de Roboflow seleccionadas, utilizando los elementos devueltos en la previsualización.
{
"apiKey": "ROBOFLOW_API_KEY",
"items": [
{
"workspace": "my-workspace",
"projectId": "warehouse-safety",
"projectName": "Warehouse Safety",
"projectType": "object-detection",
"latestVersion": 4
}
]
}Respuesta (201): matrices imported, failed y skipped. Las importaciones necesitan espacio de almacenamiento disponible y el tamaño de cada conjunto de datos debe respetar el límite por importación de tu plan.
API de cuenta#
Consulta tu cuenta de Platform, tus claves, el almacenamiento y los perfiles públicos. Consulta la documentación de configuración.
Resumen de la cuenta#
GET /api/account/summarySDK de Python: client.account.summary()
Devuelve el plan, el saldo de créditos y el recuento de recursos del espacio de trabajo que emitió la clave.
{
"username": "acme-vision",
"name": "Acme Vision",
"accountType": "team",
"plan": "pro",
"creditsCents": 2500,
"counts": { "projects": 4, "datasets": 7, "models": 21 },
"teams": []
}En una cuenta personal, teams enumera los espacios de trabajo de equipo a los que perteneces, cada uno con tu role y un deniedReason cuando no se puede acceder al espacio de trabajo, por ejemplo, si ha caducado su plan. Los espacios de trabajo de equipo devuelven una lista vacía.
Listar claves de API#
GET /api/api-keysSDK de Python: client.account.api_keys()
Devuelve keys con keyId, name, keyPrefix y createdAt del espacio de trabajo de la clave. Las solicitudes autenticadas con una clave de API reciben solo metadatos; el propietario del espacio de trabajo puede ver los valores completos de las claves en Configuración > Claves de API, en la interfaz de usuario de Platform, donde también se crean y revocan las claves.
Comprobar uso del almacenamiento#
GET /api/storageSDK de Python: client.account.storage()
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
details | booleano | Incluye los diez elementos que más almacenamiento consumen (predeterminado: false) |
Respuesta:
{
"tier": "pro",
"usage": {
"storage": { "current": 1073741824, "limit": 536870912000, "percent": 0 },
"datasets": { "current": 2, "limit": -1, "percent": 0 },
"models": { "current": 4, "limit": 500, "percent": 1 }
},
"breakdown": {
"byCategory": {
"datasets": { "bytes": 536870912, "count": 2 },
"models": { "bytes": 268435456, "count": 4 },
"exports": { "bytes": 268435456, "count": 3 }
},
"topItems": [
{
"_id": "65f1c0a2b3d4e5f601234567",
"name": "Warehouse",
"slug": "warehouse",
"sizeBytes": 536870912,
"type": "dataset"
}
]
},
"region": "us",
"username": "acme-vision",
"updatedAt": "2026-01-15T10:00:00Z"
}usage informa de los recuentos de projects, datasets, models, images, annotations y deployments, y de los bytes de storage. Un limit igual a -1 indica que no hay límite, y percent es un porcentaje entero del límite.
Obtener perfil público de usuario#
GET /api/usersSDK de Python: client.account.profile(username=...)
Parámetros de consulta:
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
username | string | Sí | Nombre de usuario que se buscará |
Devuelve el perfil público user con followerCount y, para los usuarios autenticados, isFollowed.
Seguir o dejar de seguir a un usuario#
PATCH /api/usersSDK de Python: client.account.follow(username=..., followed=...)
{
"username": "target-user",
"followed": true
}Respuesta: followed y el followerCount actualizado.
API de facturación#
Consulta el uso de tu plan y tu libro de créditos. Consulta la documentación de facturación.
Los importes de facturación son números enteros en centavos de dólar estadounidense, donde 100 = $1.00.
Ver el plan y el uso#
GET /api/billing/usage-summarySDK de Python: client.billing.usage_summary()
Devuelve plan (ID, estado, ciclo de facturación, fin del periodo), metrics (límite y uso del almacenamiento), trainingCredit, features, creditsCents y el número de puestos.
Ver transacciones#
GET /api/billing/transactionsSDK de Python: client.billing.transactions()
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
from | string | Marca de tiempo de la transacción más antigua (ISO 8601) |
to | string | Marca de tiempo de la transacción más reciente (ISO 8601) |
Cada transacción incluye id, type (como purchase, training, monthly_grant o refund), amountCents, balanceAfter, createdAt, un receiptUrl opcional y el contexto del modelo para los cargos de entrenamiento. Nunca se devuelven detalles internos de facturación.
Explorar API#
Busca proyectos públicos y conjuntos de datos compartidos por la comunidad, o busca imágenes según lo que muestran. Consulta la documentación de Explorar.
Buscar contenido público#
GET /api/explore/searchSDK de Python: client.explore.search()
Parámetros de consulta:
| Parámetro | Tipo | Descripción |
|---|---|---|
q | string | Término de búsqueda (máximo 200 caracteres); en los conjuntos de datos, primero se muestran las coincidencias de texto y, después, los conjuntos de datos cuyas imágenes coinciden |
type | string | all (predeterminado), projects, datasets o images (ignora sort) |
sort | string | newest (predeterminado), oldest, stars, name-asc, name-desc, count-desc, count-asc |
offset | int | Resultados que se omitirán (predeterminado: 0) |
limit | int | Máximo de resultados por tipo de recurso (predeterminado: 20, máx.: 100) |
task | string | Filtros de tarea separados por comas: detect, segment, semantic, depth, classify, pose, obb |
license | string | Identificadores de licencia separados por comas, como CC-BY-4.0,MIT; las imágenes tienen la misma licencia que su conjunto de datos |
author | string | Filtro por nombre de usuario del propietario |
starred | booleano | Devuelve solo el contenido marcado como favorito por quien realiza la solicitud autenticada; requiere una clave de API |
Respuesta: projects, datasets y hasMore. type=images devuelve sus coincidencias en images, empezando por la mejor; cada una incluye su dataset de origen y un score de similitud de 0–1. Requiere q y busca en conjuntos de datos públicos, además de los tuyos y los de tu equipo si envías una clave API.
curl "https://platform.ultralytics.com/api/explore/search?type=datasets&task=detect&sort=stars&limit=20"SDK de Python#
ultralytics-platform es un cliente de Python tipado generado a partir del contrato OpenAPI, con un método por punto de conexión (client.datasets.list, client.models.predict, client.exports.create, ...). Cada método acepta los parámetros de ruta como argumentos posicionales, las demás entradas como argumentos con nombre y timeout y extra_headers opcionales por solicitud.
pip install "ultralytics-platform>=0.1.45" # Python 3.11+from ultralytics_platform import Platform
with Platform() as client: # lee ULTRALYTICS_API_KEY o la clave guardada por yolo login
dataset = client.datasets.retrieve("acme-vision", "warehouse")
images = client.datasets.images("acme-vision", "warehouse", limit=10)
export = client.exports.create("acme-vision", "inspection", "v3", format="onnx")AsyncPlatform expone el mismo árbol de recursos para el código de async/await; las respuestas no satisfactorias generan APIError con status_code, body y json analizado, y los fallos de conexión generan APIConnectionError. Consulta el repositorio del SDK para ver el README completo.
Integración con Python#
Para los flujos de trabajo de entrenamiento e inferencia, usa el paquete de Python de Ultralytics, que gestiona automáticamente la autenticación, las cargas y la transmisión de métricas en tiempo real. En Python 3.11 o posterior, pip install ultralytics también instala el SDK ultralytics-platform. Cuando model.train(project=...) apunta a Platform, las devoluciones de llamada de entrenamiento transmiten eventos a través de client.training.metrics() del SDK y solicitan URL para cargar puntos de control mediante client.models.upload_checkpoint(), las operaciones POST /api/webhooks/training/metrics y POST /api/webhooks/models/upload del documento OpenAPI, así que no tienes que llamar a nada por tu cuenta.
Instalación y configuración#
La integración con Platform requiere Python>=3.11 y ultralytics>=8.4.120:
pip install "ultralytics>=8.4.120"Verifica la instalación:
yolo checkAutenticación#
yolo login YOUR_API_KEYUsar conjuntos de datos de la plataforma#
Referencia conjuntos de datos con URI ul://:
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
# Entrena con tu conjunto de datos de Platform
model.train(
data="ul://your-username/datasets/your-dataset",
epochs=100,
imgsz=640,
)Formato de URI:
| Patrón | Descripción |
|---|---|
ul://username/datasets/slug | Conjunto de datos |
ul://username/project/model-name | Modelo específico |
ul://ultralytics/yolo26/yolo26n | Modelo oficial |
Enviar a Platform#
Envía los resultados a un proyecto de Platform:
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
# Los resultados se sincronizan automáticamente con Platform
model.train(
data="coco8.yaml",
epochs=100,
project="your-username/my-project",
name="experiment-1",
)Qué se sincroniza:
- Métricas de entrenamiento (en tiempo real)
- Pesos finales del modelo
- Gráficos de validación
- La salida de la consola
- Métricas del sistema
- Argumentos de entrenamiento y entorno del host (nombre del host, SO, Python, hardware, confirmación de Git, línea de comandos)
Ejemplos de API#
Carga un modelo desde Platform:
# Tu propio modelo
model = YOLO("ul://username/project/model-name")
# Modelo oficial
model = YOLO("ul://ultralytics/yolo26/yolo26n")Ejecuta la inferencia:
results = model("image.jpg")
# Accede a los resultados
for r in results:
boxes = r.boxes # Cuadros delimitadores de detección
masks = r.masks # Máscaras de segmentación
keypoints = r.keypoints # Puntos clave de pose
probs = r.probs # Probabilidades de clasificaciónExporta el modelo:
# Exporta a ONNX
model.export(format="onnx", imgsz=640, quantize=16)
# Exportar a TensorRT
model.export(format="engine", imgsz=640, quantize=16)
# Exporta a CoreML
model.export(format="coreml", imgsz=640) # usa imgsz=224 para clasificaciónValidación:
metrics = model.val(data="ul://username/datasets/my-dataset")
print(f"mAP50: {metrics.box.map50}")
print(f"mAP50-95: {metrics.box.map}")Preguntas frecuentes#
Usa los segmentos de propietario y nombre que aparecen en la URL de Platform. Un modelo en
https://platform.ultralytics.com/acme-vision/inspection/v3esGET /api/models/acme-vision/inspection/v3. Los ID de base de datos se siguen devolviendo en las respuestas (comoid), y algunas rutas los aceptan directamente: las rutas de imagen aceptan unimageId, las cargas aceptan unassetIdyPOST /api/training/startacepta unmodelId.Depende de la colección. La mayoría de los puntos de conexión de lista aceptan
limit:curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://platform.ultralytics.com/api/datasets/acme-vision?limit=50"Las imágenes de conjuntos de datos, la agrupación en clústeres y la búsqueda de Explorar usan
offsetconlimite indicanhasMore:curl "https://platform.ultralytics.com/api/explore/search?type=datasets&offset=20&limit=20&sort=stars"Para recorrer conjuntos de imágenes muy grandes, lo mejor es usar el cursor devuelto como
nextCursor:curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://platform.ultralytics.com/api/datasets/acme-vision/warehouse/images?limit=1000&includeTotal=false&cursor=LAST_IMAGE_ID"La papelera usa
page, y los registros de implementación usan el valor opacopageTokendevuelto comonextPageToken.Sí. Todas las operaciones de esta página son solicitudes HTTPS estándar, y el contrato completo está publicado como OpenAPI 3.2 en platform.ultralytics.com/openapi.json, que puedes proporcionar a un generador de clientes en cualquier lenguaje. El paquete
ultralytics-platformes precisamente eso: un cliente tipado generado a partir del contrato, mientras que el paqueteultralyticsañade transmisión de métricas en tiempo real y cargas automáticas de modelos al entrenamiento y la inferencia. Los flujos de cuenta que solo funcionan con una sesión del navegador, como el pago de la facturación y la gestión del equipo, siguen estando en la interfaz de Platform.Usa la cabecera
Retry-Afterde la respuesta429para esperar el tiempo adecuado:import time import requests def api_request_with_retry(url, headers, max_retries=3): for attempt in range(max_retries): response = requests.get(url, headers=headers) if response.status_code != 429: return response wait = int(response.headers.get("Retry-After", 2**attempt)) time.sleep(wait) raise RuntimeError("Rate limit exceeded")404significa que el recurso no existe o que tu clave no puede verlo.403significa que se ha encontrado el recurso, pero la acción requiere más acceso del que tiene tu clave: acceso de editor para modificar un conjunto de datos, acceso de propietario para eliminar una implementación, acceso de administrador para desconectar el almacenamiento o un plan o cuota superiores para exportaciones e implementaciones.Leer conjuntos de datos, proyectos y modelos públicos, incluidas sus imágenes, URL de imagen firmadas, estadísticas de clases, estado de inserciones, distribución de agrupación en clústeres, modelos entrenados con un conjunto de datos y lista de exportaciones; consultar el progreso del entrenamiento de un modelo público; descargar los archivos de un modelo público; ejecutar inferencias con un modelo público; consultar el perfil de un usuario público; mostrar las implementaciones filtradas por un modelo público; y buscar en Explorar.
GET /api/training/gpu-availabilityes completamente público, a menos que solicites capacidad gestionada. Todo lo demás requiere una clave y, si proporcionas una en un punto de conexión público, también se mostrarán tus recursos privados.