> ## Documentation Index
> Fetch the complete documentation index at: https://www.macaly.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload asset

> Sube un archivo a un chat y obtén una URL de CDN permanente

Sube un archivo a los Recursos de un chat y devuelve una URL de CDN permanente. Úsalo para imágenes, documentos, audio, vídeo o cualquier otro archivo que quieras que tu app o proceso referencie mediante una URL.

## Solicitud

```
POST /api/client-app/assets/upload
```

### Encabezados

| Encabezado | Obligatorio | Descripción |
| - | - | - |
| `Authorization` | Sí | `Bearer macaly_...` |
| `Content-Type` | Sí | `multipart/form-data` |

### Parámetros del formulario

| Campo | Tipo | Obligatorio | Predeterminado | Descripción |
| - | - | - | - | - |
| `chatId` | string | Sí | - | El chat al que se sube el recurso |
| `file` | file | Sí | - | El archivo que se va a subir. Tamaño máximo 20 MB |
| `folderPath` | string | No | - | Ruta de carpeta separada por barras, por ejemplo `images/products` |
| `createFolders` | string | No | `false` | `"true"`, `"1"` o `"yes"` crea las carpetas de `folderPath` que falten |
| `folderId` | string | No | - | ID de una carpeta existente. No envíes `folderId` y `folderPath` a la vez |
| `title` | string | No | Nombre original del archivo | Título visible del recurso |
| `metadata` | string (JSON) | No | - | Objeto JSON que se almacena junto con el recurso |

<Note>
  Indica `folderId` o `folderPath`, no ambos. Si envías los dos, se devuelve un error 400.
</Note>

### Solicitud de ejemplo

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://www.macaly.com/api/client-app/assets/upload \
    -H "Authorization: Bearer macaly_abc123..." \
    -F "chatId=abc123def456" \
    -F "file=@./logo.png;type=image/png"
  ```

  ```javascript JavaScript theme={null}
  const form = new FormData();
  form.append('chatId', 'abc123def456');
  form.append('file', fileBlob, 'logo.png');

  const response = await fetch('https://www.macaly.com/api/client-app/assets/upload', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer macaly_abc123...',
    },
    body: form,
  });

  const data = await response.json();
  console.log(data.asset.url);
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://www.macaly.com/api/client-app/assets/upload',
      headers={'Authorization': 'Bearer macaly_abc123...'},
      data={'chatId': 'abc123def456'},
      files={'file': ('logo.png', open('logo.png', 'rb'), 'image/png')},
  )

  data = response.json()
  print(data['asset']['url'])
  ```
</CodeGroup>

### Subir a una carpeta

Usa `folderPath` para una estructura de carpetas legible y define `createFolders=true` para crear las carpetas que falten en la ruta:

```bash cURL theme={null}
curl -X POST https://www.macaly.com/api/client-app/assets/upload \
  -H "Authorization: Bearer macaly_abc123..." \
  -F "chatId=abc123def456" \
  -F "folderPath=images/products" \
  -F "createFolders=true" \
  -F "title=Product hero image" \
  -F "file=@./hero.png;type=image/png"
```

## Respuesta

```json theme={null}
{
  "success": true,
  "asset": {
    "assetId": "asset_123",
    "url": "https://cdn.macaly.app/user/chat/key/logo.png",
    "storageKey": "user/chat/key/logo.png",
    "contentType": "image/png",
    "fileSize": 12345,
    "type": "image",
    "folderId": "folder_123"
  }
}
```

| Campo | Tipo | Descripción |
| - | - | - |
| `asset.assetId` | string | Identificador único del recurso |
| `asset.url` | string | URL de CDN permanente del archivo subido |
| `asset.storageKey` | string | Ruta de almacenamiento interna |
| `asset.contentType` | string | Tipo MIME del archivo subido |
| `asset.fileSize` | number | Tamaño del archivo en bytes |
| `asset.type` | string | Tipo de recurso inferido, por ejemplo `image`, `document` |
| `asset.folderId` | string \| null | Carpeta en la que se colocó el recurso, si la hay |

## Códigos de estado

| Código | Descripción |
| - | - |
| 200 | Correcto: recurso subido |
| 400 | Falta `chatId` o `file`, el JSON de `metadata` no es válido, o se enviaron `folderId` y `folderPath` a la vez |
| 401 | Clave API no válida o ausente |
| 403 | La clave API no tiene acceso a este chat |
| 404 | Carpeta no encontrada |
| 413 | El archivo supera el límite de 20 MB |
| 500 | Error del servidor |

## Reglas de las carpetas

* Las rutas de carpeta se separan por `/`, se recortan los espacios y se ignoran los segmentos vacíos.
* La profundidad máxima es de 8 carpetas.
* Cada nombre de carpeta puede tener hasta 255 caracteres.
* La coincidencia de carpetas no distingue mayúsculas de minúsculas dentro del mismo elemento superior.
* Si `folderPath` no existe y `createFolders` no es `true`, la subida falla con un error 404.

## Es útil saber que

* Este endpoint usa la misma clave API `macaly_...` que el resto de la API, aunque la URL empiece por `/api/client-app/`. No se necesita un token independiente.
* El chat referenciado por `chatId` debe pertenecer al mismo equipo que tu clave API.
* Los recursos subidos obtienen una URL de CDN permanente que puedes referenciar en [Create chat](/docs/es/api/create-chat) o [Publish message](/docs/es/api/publish-message) como archivo adjunto, o usar en cualquier lugar fuera de Macaly.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.