> ## 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.

# Obtener un producto

> Devuelve un producto por su id, en la misma forma plana que acepta el upsert. Responde `404` igual para un id que no existe, uno de otro tenant y uno del simulador: nombrar la diferencia permitiría sondear ids ajenos.



## OpenAPI

````yaml /openapi.json get /products/public/v1/{id}
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, organizaciones, 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: Organizaciones
    description: >-
      Sincroniza empresas por identificador tributario, con atributos
      personalizados por nombre.
  - 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:
  /products/public/v1/{id}:
    get:
      tags:
        - Productos
      summary: Obtener un producto
      description: >-
        Devuelve un producto por su id, en la misma forma plana que acepta el
        upsert. Responde `404` igual para un id que no existe, uno de otro
        tenant y uno del simulador: nombrar la diferencia permitiría sondear ids
        ajenos.
      operationId: getProduct
      parameters:
        - name: id
          in: path
          required: true
          description: Id del producto en Revem.
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: El producto.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '400':
          description: El id no es un UUID.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductsError'
        '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 credencial no puede usar esta ruta. Una API key sólo alcanza los
            endpoints documentados aquí; cualquier otra ruta de la API responde
            este código.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthError'
              example:
                ok: false
                error: Forbidden
                message: This endpoint is not available to API keys
        '404':
          description: No hay un producto visible con ese id.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductsError'
              example:
                ok: false
                error: Not Found
                message: No existe un producto con ese id
        '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:
    Product:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: ID estable del producto en Revem, incluso si cambia el SKU.
        sku:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Siempre presente. Es null en un producto creado desde la app sin
            SKU: existe, pero no se puede direccionar por SKU.
        name:
          type: string
          description: Nombre del producto.
        description:
          type: string
          description: Descripción; omitida si no se conoce.
        price:
          type: number
          description: Precio con hasta dos decimales.
        currency:
          type: string
          description: Código de moneda de 3 letras; omitido si no se conoce.
        billing_frequency:
          type: string
          enum:
            - UNIQUE
            - WEEKLY
            - MONTHLY
            - QUARTERLY
            - SEMI_ANNUAL
            - ANNUAL
          description: Frecuencia de cobro.
        billing_model:
          type: string
          enum:
            - UNIQUE
            - RECURRENT
          description: Modelo de cobro; omitido si no se conoce.
        unit_of_measurement:
          type: string
          enum:
            - UNIT
            - HOUR
            - DAY
            - MONTH
            - KG
            - G
            - LITER
            - METER
            - M2
          description: Unidad de medida; omitida si no se conoce.
        maximum_percentage_discount:
          type: integer
          description: Descuento máximo permitido; omitido si no se conoce.
        tax:
          type: integer
          description: Impuesto aplicable; omitido si no se conoce.
        active:
          type: boolean
          description: Si el producto está disponible.
        media_url:
          type: string
          description: Enlace a la imagen; omitido si no hay.
        external_url:
          type: string
          description: Enlace donde se ve o se compra; omitido si no hay.
        externally_managed:
          type: boolean
          description: >-
            Sólo lectura. true cuando una integración importó el producto y
            administra media_url y external_url: escribirlos responde 409.
        created_at:
          type: string
          format: date-time
          description: Fecha de creación, ISO 8601 en UTC.
        updated_at:
          type: string
          format: date-time
          description: Última modificación, ISO 8601 en UTC.
      required:
        - id
        - sku
        - name
        - price
        - billing_frequency
        - active
        - externally_managed
        - created_at
        - updated_at
      additionalProperties: true
      description: >-
        Campos snake_case y atributos de producto por nombre al mismo nivel. Los
        valores ausentes se omiten, salvo sku que siempre está presente. Un
        atributo cuya definición se borró, o que se llama igual que un campo
        publicado, no se devuelve.
      example:
        id: 3f2b6c1e-8d4a-4f0b-9c2e-7a1d5e6f8b90
        sku: CONT-20ST
        name: Contenedor 20 pies
        description: Contenedor dry standard de 20 pies
        price: 1250000
        currency: CLP
        billing_frequency: UNIQUE
        billing_model: UNIQUE
        unit_of_measurement: UNIT
        tax: 19
        active: true
        externally_managed: false
        Estado: Disponible
        created_at: '2026-09-01T12:00:00.000Z'
        updated_at: '2026-09-02T12:00:00.000Z'
    ProductsError:
      type: object
      properties:
        ok:
          type: boolean
          const: false
        error:
          type: string
          description: Etiqueta del error.
        message:
          type: string
          description: Explicación legible del problema.
        unknownAttributes:
          type: array
          items:
            type: string
          description: >-
            Presente en el 422 por atributos: los nombres desconocidos, de sólo
            lectura u obligatorios que faltan.
        missingAttributes:
          type: array
          items:
            type: string
      required:
        - 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.

````