Documentación de la API
API REST para transcripción de audio y video. Los clientes de pago autentican integraciones de terceros con una clave API creada en la configuración de la cuenta.
URL base
https://scribe.uustudio.cc
Autenticación
Las integraciones de terceros deben enviar una clave API de una cuenta de pago en la cabecera Authorization.
Cabecera Authorization
Authorization: Bearer {token}Crea y revoca claves API desde la página Claves API de la configuración. Los endpoints de autenticación de la app están reservados para clientes propios.
Respuestas de error
Todos los errores devuelven un cuerpo JSON con un campo message .
Error estándar
{
"message": "Description of the error"
}Error de validación (422)
{
"message": "The name field is required.",
"errors": {
"name": ["The name field is required."]
}
}| Estado | Descripción |
|---|---|
| 401 | No autenticado (token faltante o inválido) |
| 403 | Prohibido o límite del plan excedido |
| 404 | Recurso no encontrado |
| 422 | Validación fallida |
| 429 | Límite de velocidad o demasiadas tareas concurrentes |
| 500 | Error interno del servidor |
Límites de velocidad
Los endpoints autenticados de la API están limitados a 10 solicitudes por minuto y token.
Límites de uso
Disponibilidad de la API
La API REST de terceros no está disponible en el plan Gratis. Actualiza a Pro o Max, o compra un paquete de pago por uso, para crear y usar claves API.
- Tamaño máximo de archivo
- 2 GB
- Tareas concurrentes
- Máx 3
- Reintentos máximos por tarea
- 3
Comparación de planes de pago
| Característica | Pay as you go | Pro | Max |
|---|---|---|---|
| Subidas diarias | Ilimitado | Ilimitado | Ilimitado |
| Formatos de exportación | Todos | Todos | Todos |
| Prioridad de tareas | Media | Media | Alta |
Flujos de trabajo
Subir archivo de audio/video
POST /api/uploads/sign→ Obtener upload_id e información de partesPUT {presigned_url}→ Subir cada parte al almacenamientoPOST /api/uploads/complete→ Finalizar subida, auto-crear tareaGET /api/tasks/{id}→ Consultar estado (pending -> scribing -> finished)GET /api/tasks/{id}/download/srt→ Exportar (opcional)
Crear tarea manualmente
POST /api/tasks→ Crear con disk, path, nameGET /api/tasks/{id}→ Consultar estadoGET /api/tasks/{id}→ Obtener segments, summary, mindmap
Auth
/api/loginAutentícate con correo y contraseña. Devuelve un token de Sanctum.
Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| string | Yes | Correo del usuario (máx 255) | |
| password | string | Yes | Contraseña del usuario |
Respuesta 200
{
"token": "1|abc123...",
"user": {
"id": 1,
"name": "Zhang San",
"email": "[email protected]"
}
}Limitado a 5 intentos por minuto por correo.
/api/registerCrea una cuenta nueva. Devuelve un token de Sanctum.
Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| name | string | Yes | Nombre para mostrar (máx 255) |
| string | Yes | Correo único (máx 255) | |
| password | string | Yes | Debe ser confirmado |
| password_confirmation | string | Yes | Confirmación de contraseña |
Respuesta 201
{
"token": "1|abc123...",
"user": {
"id": 1,
"name": "Zhang San",
"email": "[email protected]"
}
}/api/logoutRevoca el token de acceso actual.
Respuesta 204
No devuelve cuerpo.
Tareas
/api/tasksCrea una tarea de transcripción. Máx 3 tareas concurrentes por usuario.
Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| disk | string | Yes | r2 / remote / youtube Identificador de la fuente de almacenamiento |
| name | string | Yes | Nombre de la tarea (máx 255) |
| path | string | Yes | Ruta del archivo o URL de origen |
| file | string | No | Nombre de archivo original (máx 255) |
| size | integer | No | Tamaño del archivo en bytes |
| duration | integer | No | Duración en segundos |
| cost | integer | No | Costo en segundos |
| segments | array | No | Segmentos de transcripción |
| speaker_diarization | boolean | No | app.tasks.speaker_diarization_api_description |
Respuesta 201
{
"id": 1,
"name": "Meeting Recording",
"status": "pending",
"speaker_diarization": true,
"created_at": "2026-03-02T10:30:00+08:00"
}Errores
| Estado | Descripción |
|---|---|
| 403 | Los usuarios gratuitos no pueden enviar enlaces de YouTube mediante la API. |
| 429 | Máximo de 3 tareas concurrentes alcanzado |
/api/tasks/{id}Obtén los detalles completos de la tarea, incluyendo los resultados de transcripción.
Respuesta
{
"id": 1,
"name": "Meeting Recording",
"file": "meeting.mp3",
"path": "2026-03-02/01HQX...mp3",
"disk": "r2",
"size": 50545869,
"duration": 1965,
"cost": 33,
"status": "finished",
"attempts": 1,
"quality": 3,
"created_at": "2026-03-02T10:30:00+08:00",
"updated_at": "2026-03-02T10:45:00+08:00",
"summary": "The meeting discussed three topics...",
"mindmap": "# Topic\n## Sub-topic 1",
"folder": "Work",
"tags": ["Work"],
"url": "https://youtube.com/watch?v=...",
"segments": [
{
"id": 1,
"start": 0,
"end": 5000,
"speaker": "Speaker 1",
"tokens": ["Okay", "so let's", "begin"],
"text": "Okay, so let's begin..."
}
],
"export": {
"allowed_formats": ["txt", "srt", "vtt", "csv", "pdf", "docx"],
"heavy_formats": ["pdf", "docx"],
"version": "20260302104500"
}
}Campos de respuesta
| Campo | Tipo | Descripción |
|---|---|---|
| disk | string|null | Disco de almacenamiento: r2 / remote / youtube |
| size | int|null | Tamaño del archivo en bytes |
| cost | int|null | Costo en segundos |
| attempts | int | Recuento de reintentos |
| quality | int|null | Puntuación de calidad (0-5) |
| summary | string|null | Resumen generado por IA |
| mindmap | string|null | Mapa mental generado por IA |
| folder | string|null | Nombre de la primera etiqueta (carpeta) |
| tags | array | Todos los nombres de etiquetas |
| url | string|null | URL de origen (para tareas de YouTube) |
| segments | array|null | Segmentos de transcripción |
| segments[].start | int | Tiempo de inicio (ms) |
| segments[].end | int | Tiempo de fin (ms) |
| segments[].text | string | Texto del segmento |
| segments[].speaker | string|null | Identificador del hablante |
| segments[].tokens | array|null | Array de tokens de palabras |
| export | object | Metadatos de exportación (allowed_formats, heavy_formats, version) |
/api/tasksParámetros de consulta
| Parámetro | Tipo | Por defecto | Descripción |
|---|---|---|---|
| status | string | all | Filtrar por estado |
| search | string | — | Buscar por nombre |
| folder | string | — | Filtrar por carpeta (o Uncategorized) |
| page | int | 1 | Número de página |
| per_page | int | 25 | Elementos por página (máx 100) |
Respuesta
{
"data": [
{
"id": 1,
"name": "Meeting Recording",
"file": "meeting.mp3",
"disk": "r2",
"size": 50545869,
"duration": 1965,
"cost": 33,
"status": "finished",
"attempts": 1,
"quality": 3,
"folder": "Work",
"created_at": "2026-03-02T10:30:00+08:00"
}
],
"current_page": 1,
"last_page": 1,
"per_page": 25,
"total": 1
}/api/tasks/{id}/retryReintentar una tarea fallida. Establece el estado a pending (R2) o waiting (remote/YouTube). Máx 3 reintentos.
Respuesta 200
{
"id": 1,
"status": "pending",
"attempts": 2
}/api/tasks/{id}/download/{format}Exportar transcripción. Los formatos ligeros devuelven el archivo directamente. Los formatos pesados (pdf/docx) pueden devolver 202 mientras se procesan.
Parámetros de ruta
| Parámetro | Descripción |
|---|---|
| format | txt / srt / vtt / csv / pdf / docx |
Respuestas
200 - Archivo listo (formatos ligeros)
Devuelve un archivo binario.
200 - Archivo listo (formatos pesados, solicitud JSON)
{
"status": "ready",
"url": "https://scribe.uustudio.cc/api/tasks/1/download/pdf"
}202 - Procesando formato pesado
{
"status": "processing",
"message": "Your export is being generated. Please try again shortly."
}/api/tasks/{id}/audioTransmitir el archivo de audio o video original directamente desde el almacenamiento (solo R2).
Respuesta
200 - Flujo binario del archivo de audio o video. Devuelve 404 si el archivo falta o no está almacenado en el disco R2.
/api/tasks/{id}/refresh-summaryActualizar y devolver el resumen y mapa mental generados por IA más recientes.
Respuesta
{
"summary": "The meeting discussed three topics...",
"mindmap": "# Topic\n## Sub-topic 1"
}/api/tasks/{id}Actualizar campos de la tarea. Todos los campos son opcionales.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
| name | string | Nuevo nombre (máx 255) |
| folder | string|null | Nombre de carpeta (null elimina la tarea de una carpeta) |
| duration | integer | Duración en segundos |
| cost | integer | Costo en segundos |
| segments | array | Array completo de segmentos para reemplazar |
| text | string | Texto completo de la transcripción |
| quality | integer | Puntuación de calidad (0-5) |
| index | integer | Índice de orden de la tarea |
Respuesta 200
Devuelve el objeto de tarea completo (igual que Detalle de tarea).
/api/tasks/{id}Response 200
{
"message": "Task deleted successfully"
}/api/tasks/bulkEliminar múltiples tareas a la vez. Solo se eliminarán las tareas del usuario autenticado. Los IDs que no pertenezcan al usuario se ignoran.
Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| ids | array | Yes | Array de IDs de tareas a eliminar (mín 1) |
Respuesta 200
{
"message": "2 task(s) deleted successfully",
"deleted_count": 2
}/api/tasks/bulk/moveMover múltiples tareas a una carpeta a la vez. Solo se moverán las tareas del usuario autenticado.
Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| ids | array | Yes | Array de IDs de tareas a mover (mín 1) |
| folder | string | Yes | Nombre de la carpeta de destino (máx 255) |
Respuesta 200
{
"message": "2 task(s) moved to Work",
"moved_count": 2
}Subidas
Subida multipart/api/uploads/signCuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| file | string | Yes | Nombre de archivo (debe usar un formato soportado) |
| content_type | string | Yes | Tipo MIME (debe coincidir con la extensión del archivo) |
| size | integer | Yes | Tamaño del archivo en bytes (máx 2,147,483,648 / 2 GB) |
| duration | integer | No | Duración del audio en segundos |
Respuesta
{
"path": "2026-03-02/01HQX...mp3",
"upload_id": "abc123",
"part_size": 5242880,
"part_count": 10,
"expires_at": "2026-03-02T10:40:00+08:00"
}/api/uploads/sign-partCuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| path | string | Yes | Ruta de subida (máx 2048) |
| upload_id | string | Yes | ID de subida (máx 2048) |
| part_number | integer | Yes | Número de parte (1-10000) |
Respuesta
{
"url": "https://storage.example.com/...?X-Amz-...",
"headers": {
"Content-Type": "audio/mpeg"
}
}Usa PUT con la URL y las cabeceras devueltas para subir la parte.
/api/uploads/completeCompletar una subida multipart. Esto crea automáticamente una tarea y devuelve 403 cuando la API no está disponible o se supera un límite del plan.
Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| path | string | Yes | Ruta de subida (máx 2048) |
| upload_id | string | Yes | ID de subida (máx 2048) |
| original_name | string | Yes | Nombre de archivo original (debe usar un formato soportado) |
| content_type | string | Yes | Tipo MIME (debe coincidir con la extensión del archivo) |
| size | integer | Yes | Tamaño del archivo en bytes (máx 2 GB) |
| name | string | No | Nombre de tarea (por defecto usa el nombre de archivo sin extensión) |
| duration | integer | No | Duración en segundos (mín 1) |
| speaker_diarization | boolean | No | app.tasks.speaker_diarization_api_description |
Respuesta 201
{
"message": "File uploaded to the upload server successfully.",
"task": {
"id": 1,
"name": "meeting",
"path": "2026-03-02/01HQX...mp3",
"size": 50545869,
"status": "pending",
"speaker_diarization": true
}
}/api/uploads/abortCuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| path | string | Yes | Ruta de subida (máx 2048) |
| upload_id | string | Yes | ID de subida (máx 2048) |
Respuesta
{
"message": "Multipart upload cancelled successfully."
}Carpetas
Basado en etiquetas/api/foldersLista todas las carpetas con recuentos de tareas.
Respuesta
{
"folders": [
{"id": 1, "name": "Work", "count": 5},
{"id": 2, "name": "Personal", "count": 3}
],
"uncategorized_count": 2,
"total_count": 10
}/api/foldersCuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| name | string | Yes | Nombre de carpeta (máx 14 caracteres / 7 caracteres chinos, único por usuario) |
Respuesta 201
{
"id": 1,
"name": "Work"
}/api/folders/{name}Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| name | string | Yes | Nuevo nombre de carpeta (mismas restricciones que crear) |
Respuesta 200
{
"id": 1,
"name": "New Name"
}/api/folders/{name}Response 200
{
"message": "Folder deleted successfully"
}Usuario
/api/userRespuesta
{
"id": 1,
"name": "Zhang San",
"email": "[email protected]",
"avatar": "https://...",
"balance": {
"used_seconds": 9000,
"remaining_seconds": 36000,
"allowance_remaining_seconds": 30000,
"top_up_remaining_seconds": 6000,
"total_seconds": 45000,
"usage_percent": 20
},
"subscription": {
"plan": "year",
"plan_key": "max_yearly",
"tier": "max",
"billing_interval": "yearly",
"active": true,
"access_tier": "max"
},
"queue": {
"pending_count": 1,
"running_count": 1,
"failed_count": 0
}
}Campos de saldo
| Campo | Tipo | Descripción |
|---|---|---|
| used_seconds | int | Segundos usados desde el último otorgamiento mensual |
| remaining_seconds | int | Segundos restantes |
| total_seconds | int | Segundos totales |
| usage_percent | int | Porcentaje de uso (0-100) |
/api/userCuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| name | string | No | Nombre para mostrar (máx 255) |
| string | No | Nuevo correo (debe ser único) | |
| avatar | file | No | Archivo de imagen (máx 5 MB) |
Respuesta 200
{
"id": 1,
"name": "New Name",
"email": "[email protected]",
"avatar": "https://..."
}Notificaciones
/api/notificationsObtener las 10 notificaciones más recientes.
Respuesta
[
{
"id": "abc123",
"title": "Task Completed",
"message": "Meeting Recording has been transcribed.",
"read_at": null,
"created_at": "2026-03-02T10:45:00+08:00"
}
]/api/notifications/mark-all-as-readMarcar todas las notificaciones no leídas como leídas.
Response 200
{
"success": true
}Pago
/api/checkout/{plan}Obtener una URL de pago de Paddle para un plan de suscripción.
Parámetros de ruta
| Parámetro | Descripción |
|---|---|
| plan | test / month / year |
Respuesta
Devuelve un objeto de opciones de checkout de Paddle. Devuelve 404 para un plan inválido.
/api/healthEndpoint público de verificación de estado. No requiere autenticación.
Respuesta 200
{
"status": "ok"
}
/api/auth/social-loginAutentícate a través de Google OAuth. Crea una cuenta si no existe.
Cuerpo de la solicitud
googleproveedores soportadosRespuesta 200