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

# Subir un adjunto

> Sube un archivo para adjuntarlo después a un mensaje con `POST /webchat/messages`. El cuerpo es `multipart/form-data` con un único archivo; el formato se valida por el `Content-Type` de la parte, no por la extensión del nombre.

| Formato | Límite |
| --- | --- |
| `image/png`, `image/jpeg` | 5 MB |
| `video/mp4`, `video/3gpp` | 16 MB |
| `application/pdf`, Word (`.doc`, `.docx`), Excel (`.xls`, `.xlsx`), `text/plain` | 25 MB |



## OpenAPI

````yaml /openapi.json post /webchat/media
openapi: 3.1.0
info:
  title: Revem API
  version: 1.0.0
  description: >-
    La API pública de Revem para integraciones de servidor a servidor:
    contactos, tickets y el canal de webchat. Se autentica con la API key de tu
    organización.
  contact:
    name: Soporte Revem
    email: soporte@revem.ai
    url: https://revem.ai
servers:
  - url: https://api.revem.ai
    description: Producción
security:
  - apiKey: []
tags:
  - name: Contactos
    description: >-
      Sincroniza tu base de clientes con Revem. Los contactos se identifican por
      teléfono al crearlos y por id después.
  - name: Tickets
    description: Lee y actualiza los tickets de tu embudo desde tu sistema de gestión.
  - name: Webchat
    description: >-
      Conecta el chat de tu sitio con Revem: registra lo que escribe el
      visitante y lee las respuestas del equipo o del agente.
paths:
  /webchat/media:
    post:
      tags:
        - Webchat
      summary: Subir un adjunto
      description: >-
        Sube un archivo para adjuntarlo después a un mensaje con `POST
        /webchat/messages`. El cuerpo es `multipart/form-data` con un único
        archivo; el formato se valida por el `Content-Type` de la parte, no por
        la extensión del nombre.


        | Formato | Límite |

        | --- | --- |

        | `image/png`, `image/jpeg` | 5 MB |

        | `video/mp4`, `video/3gpp` | 16 MB |

        | `application/pdf`, Word (`.doc`, `.docx`), Excel (`.xls`, `.xlsx`),
        `text/plain` | 25 MB |
      operationId: uploadWebchatMedia
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
                  description: >-
                    El archivo. Se lee la primera parte de tipo archivo,
                    cualquiera sea el nombre del campo.
              required:
                - file
      responses:
        '201':
          description: Archivo guardado.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebchatMediaUploaded'
              example:
                mediaId: d4c3b2a1-6f5e-4d7c-8b9a-0f1e2d3c4b5a
        '400':
          description: >-
            Sin archivo (`file_required`), sin nombre (`file_name_required`),
            formato no permitido (`unsupported_media_type`) o tamaño excedido
            (`file_too_large`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebchatError'
              example:
                ok: false
                error: unsupported_media_type
                message: El formato image/gif no está permitido.
        '401':
          description: Sin credencial, o la API key no existe o fue revocada.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthError'
              example:
                error: Unauthorized
                message: Invalid API key
        '403':
          description: >-
            La ruta es sólo para sistemas externos autenticados con API key
            (`inbound_requires_service_identity`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebchatError'
        '429':
          description: >-
            La key superó su límite de solicitudes por minuto. El header
            `retry-after` indica cuánto esperar.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitError'
              example:
                ok: false
                error: Too many requests. Retry in 1 minute.
          headers:
            retry-after:
              description: Segundos que esperar antes de reintentar.
              schema:
                type: integer
            x-ratelimit-limit:
              description: Solicitudes permitidas por minuto.
              schema:
                type: integer
            x-ratelimit-remaining:
              description: Solicitudes que quedan en la ventana actual.
              schema:
                type: integer
            x-ratelimit-reset:
              description: Segundos hasta que la ventana se reinicia.
              schema:
                type: integer
components:
  schemas:
    WebchatMediaUploaded:
      type: object
      properties:
        mediaId:
          type: string
          format: uuid
          description: >-
            Identificador del archivo. Úsalo en `attachments[].mediaId` de `POST
            /webchat/messages`.
      required:
        - mediaId
      additionalProperties: false
    WebchatError:
      type: object
      properties:
        ok:
          type: boolean
          const: false
        error:
          type: string
          description: >-
            Código estable del error, por ejemplo `channel_not_found`,
            `contact_identity_required` o `unsupported_media_type`.
        message:
          type: string
          description: Explicación legible del problema.
      required:
        - ok
        - error
      additionalProperties: false
    AuthError:
      type: object
      properties:
        ok:
          type: boolean
          const: false
          description: Presente sólo en el `403`.
        error:
          type: string
        message:
          type: string
      required:
        - error
        - message
    RateLimitError:
      type: object
      properties:
        ok:
          type: boolean
          const: false
        error:
          type: string
          description: Incluye cuánto esperar antes de reintentar.
      required:
        - ok
        - error
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        La API key de tu organización, con la forma `rvm_<prefijo>.<secreto>`,
        enviada como `Authorization: Bearer rvm_…`. Revem la emite y sólo se
        muestra una vez; si la pierdes se reemplaza, no se recupera.

````