> This page is for De cámara a la nube.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://next.developer.frame.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://next.developer.frame.io/_mcp/server.

# Guía práctica: Autorizar

## Introducción





En esta guía se explica el proceso de autenticación y autorización para dispositivos Camera to Cloud (C2C) en un proyecto de Frame.io. Exploraremos tanto el método estándar de entrada manual de código como el enfoque mejorado de emparejamiento con código QR para ofrecer una experiencia de usuario óptima.





## ¿Qué necesitaré?

Revise la guía [Antes de empezar la implementación](./implementing-c2c-setting-up) si aún no lo ha hecho. Debería haber recibido un `client_secret` de nuestro equipo para identificar su integración. Si no es así, consulte [esta introducción](./getting-started-with-cloud-device-integrations) al ecosistema de C2C y póngase en contacto con nuestro equipo.

### Requisitos previos para el emparejamiento con código URL y QR





Para implementar el emparejamiento con código URL y QR, asegúrese de cumplir estos requisitos:





* **Compatibilidad del dispositivo**: Verifique que su dispositivo sea compatible con la generación de código URL/QR durante el proceso de emparejamiento.




## Descripción detallada del flujo de autorización





Para entender el flujo de autorización desde la perspectiva del usuario, consulte estos recursos:




* [Artículo de asistencia](https://help.frame.io/es/collections/8960335-frame-io-c2c) para añadir dispositivos nuevos.
* [Vídeo de formación](https://help.frame.io/es/articles/5091124-camera-to-cloud-training-series) sobre la autorización de un dispositivo Teradek Cube.




Este proceso de autorización minimiza los requisitos de implementación. No necesitará:




* Redirigir a exploradores web (a menos que use el emparejamiento con código URL)
* Gestionar la autenticación de usuarios de Frame.io
* Presentar interfaces de selección de cuenta/proyecto
* Desarrollar componentes complejos de la IU más allá de las pantallas básicas de información




### Mejora de la experiencia del usuario mediante el emparejamiento con código URL





Los usuarios modernos esperan interacciones eficientes con los dispositivos. Aunque el proceso actual de emparejamiento manual funciona adecuadamente, se puede optimizar.





Al implementar el emparejamiento con código URL y QR, similar al que se usa en los servicios de streaming como Netflix o Disney+, podemos optimizar significativamente el proceso, minimizar los errores en la entrada de código y reducir el tiempo que dura el emparejamiento.





## Identificación del dispositivo (client_id)





Cada dispositivo físico requiere un identificador único para hacer el seguimiento de las conexiones dentro del proyecto de un usuario.

Para los dispositivos, este identificador es el `client_id`, que es esencial durante la autorización. Al realizar la implementación, puede utilizar las fuentes de identificador apropiadas, como los números de serie del dispositivo, los UUID u otras cadenas únicas. Si está realizando la integración en un dispositivo Apple, recomendamos usar un UUID persistente único que sea coherente durante los reinicios del dispositivo. Tenga cuidado con la información de identificación personal. Las direcciones de correo electrónico del usuario no son valores apropiados de `client_id`.

Además, asegúrese de que controla el identificador. Las direcciones MAC del dispositivo no son adecuadas ya que no son propiedad de su software y pueden constituir información de identificación personal.





Si necesita orientación para seleccionar un identificador apropiado, nuestro equipo puede ayudarle a determinar un valor adecuado que simplifique la integración.





## Paso 1: Solicitar un código de dispositivo

Para comenzar la implementación, solicite un código de dispositivo a través del punto final `/v2/auth/device/code`:

### Método de emparejamiento tradicional





```
curl -X POST https://api.frame.io/v2/auth/device/code \
    --form 'client_id=[client_id]' \
    --form 'client_secret=[client_secret]' \
    --form 'scope=asset_create offline' \
    | python -m json.tool
```





### Habilitación del emparejamiento con código URL





Para el emparejamiento con código URL, modifique la llamada API con encabezados adicionales:





```
curl -X POST https://api.frame.io/v2/auth/device/code \
    --header "x-client-version: 2.0.0" \
    --header "x-client-platypus-enabled: true" \  # New header to enable URL pairing
    --form 'client_id=[client_id]' \
    --form 'client_secret=[client_secret]' \
    --form 'scope=asset_create offline' \
    | python -m json.tool
```

**Nota:** Estos puntos finales de autenticación aceptan exclusivamente datos de formulario, no JSON. Después de la autenticación, otros puntos finales aceptarán cargas útiles JSON, pero los puntos finales de autenticación rechazarán las solicitudes JSON.

#### Parámetros de carga útil




* **client_id**: El identificador único de su dispositivo físico. Debe garantizarse que sea único, como un número de serie o un UUID.
* **client_secret**: Lo proporciona el servicio de asistencia de Frame.io para identificar su modelo de dispositivo. Este valor confidencial debe mantenerse protegido de los usuarios y cifrado cuando se almacene.
* **scope**: Los permisos solicitados, separados por espacios. Los dispositivos pueden solicitar:

* `asset_create`: Permite la creación y la carga de activos. * `offline`: Permite la actualización de autorización mediante token de actualización. Sin este ámbito, los usuarios tendrían que volver a autorizar su dispositivo cada 8 horas, ya que los tokens de autorización caducan.

En implementaciones prácticas, los dispositivos normalmente solicitan ambos ámbitos.





### Comprensión de la respuesta de la API





La solicitud genera una respuesta similar a la siguiente:





#### Respuesta de emparejamiento tradicional





```
{
  "device_code": "[device_code]",
  "expires_in": 120,
  "interval": 5,
  "name": "MyDevice-[client_id]",
  "user_code": "573131"
}
```





#### Respuesta de emparejamiento con URL





```
{
  "device_code": "[device_code]",
  "expires_in": 120,
  "interval": 5,
  "name": "MyDevice-[client_id]",
  "user_code": "573131",
  "verification_uri": "https://next.frame.io/pair",
  "verification_uri_complete": "https://next.frame.io/pair/573131"
}
```





#### Desglose de la respuesta




* **device_code**: Este identificador interno debe permanecer oculto e identifica la solicitud de autorización durante el sondeo.
* **expires_in**: El periodo de validez del código en segundos.
* **interval**: El intervalo de sondeo recomendado en segundos.
* **name**: El identificador del dispositivo de conexión.
* **user_code**: El código de seis dígitos para la entrada manual en Frame.io y realizar el emparejamiento del dispositivo.
* **verification_uri**: La URL base para la entrada manual si el escaneo del código QR no está disponible.
* **verification_uri_complete**: La URL completa que contiene el código de emparejamiento y destinada al hipervínculo dentro de una aplicación móvil o generación de código QR para optimizar la navegación del usuario a la interfaz de emparejamiento.




### Cómo mostrar el código QR al usuario

Con el `verification_uri_complete`, genere y muestre un código QR en la pantalla del dispositivo para que el usuario lo escanee, de manera que se facilite un emparejamiento eficiente.

#### Ejemplo: Pantalla del dispositivo en la que se muestra un código QR

![Ejemplo de pantalla de emparejamiento con código QR en el dispositivo](/_fern-img/193d938af906dbcbc9699953e9da5ddbeeee8cd75fdfabf0661127c2b528cdb4.webp) Proporcione siempre opciones de reserva: Muestre el `user_code` y el `verification_uri` para facilitar la entrada manual cuando el escaneo del código QR no sea posible. También puede mostrar el `verification_uri` como un código QR estático para el escaneo móvil. Para integraciones de aplicaciones móviles, incluya el `verification_uri_complete` como un hipervínculo en el que se puede pulsar, ya que los usuarios no pueden escanear códigos QR desde el dispositivo que ejecuta la aplicación.

## Paso 2: Sondear para obtener la autorización del usuario





Después de proporcionar el código de emparejamiento o código URL, verifique la entrada del usuario con esta solicitud:





```
curl -X POST https://api.frame.io/v2/auth/token \
    --form 'client_id=[client_id]' \
    --form 'device_code=[device_code]' \
    --form 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
    | python -m json.tool
```





### Parámetros de carga útil




* **client_id**: El mismo identificador que se ha utilizado en el paso 1.
* **device_code**: El valor de `device_code` devuelto anteriormente.
* **grant_type**: El identificador del tipo de concesión OAuth, siempre `urn:ietf:params:oauth:grant-type:device_code` para esta implementación.




Los intentos iniciales de sondeo normalmente devuelven:





```
{
  "error": "authorization_pending"
}
```





Este error no grave indica que el usuario no ha completado la entrada de código. Siga con el sondeo hasta que termine.



<blockquote>**Nota para dispositivos de la aplicación para iOS:** Si el usuario cambia a la aplicación para iOS de Frame.io para introducir el código de emparejamiento, puede que su aplicación pase al segundo plano. Cuando su aplicación vuelva a estar activa, como en `applicationDidBecomeActive`, reanude el sondeo para que el flujo de autorización pueda continuar sin requerir que el usuario reinicie el emparejamiento.</blockquote>



Si recibe:





```
{
  "error": "expired_token"
}
```





El código caducó antes de la entrada del usuario. Genere un código/código QR nuevo a través del paso 1, preséntelo al usuario y reanude el sondeo.





Una autorización correcta produce:





```
{
  "access_token": "[access_token]",
  "expires_in": 28800,
  "refresh_token": "[refresh_token]",
  "token_type": "bearer"
}
```





Enhorabuena por autorizar correctamente su dispositivo Camera to Cloud.





Examinemos esta respuesta:




* **access_token**: Su credencial de autenticación para el acceso al backend de Frame.io, necesaria en los encabezados para futuras solicitudes de API.
* **expires_in**: El periodo de validez del token de acceso en segundos; después de este periodo, es necesario actualizarlo.
* **refresh_token**: Se usa para la administración del token de acceso, principalmente para actualizar la autorización, pero también aplicable para la revocación.
* **token_type**: Siempre será `bearer` para implementaciones de API de C2C, sin que sea necesario realizar ninguna acción.




## Unión de todos los pasos





Ahora vamos a implementar estas llamadas API en pseudocódigo similar a Python y gestionaremos la posible caducidad del código del dispositivo:





**`Python`**

```python title="Python"
def authorize_with_frame():
    """
    Handles authorizing our device with Frame.io.
    """

    # Our client ID can be a serial number, UUID, or some other unique string.
    client_id = THIS_DEVICE.get_serial_number()

    while True:
        # Make the call to Frame.io to get our device codes.
        pairing_codes = c2c.get_device_codes(client_id)

        # We need to keep track of how long we have been polling for
        polling_started = datetime.now()

        # Now we are going to poll for authorization until the user enters the code.
        while True:

            # Re-write this output each time we poll. Note: This message will only update once
            # per `interval` (e.g., 5 seconds), so if a smooth countdown is desired, that will
            # need a different implementation.
            print(
                f"\rPAIRING CODE: {pairing_codes.user_code}, "
                f"EXPIRES IN: {pairing_codes.expires_in - (datetime.now() - polling_started).seconds} seconds"
            )

            # Wait for `interval` before polling each time.
            sleep(pairing_codes.interval)

            # Make a call to Frame.io to see if the user has entered the code and authorized
            # the device.
            authorization, error = c2c.poll_for_authorization(
                client_id, pairing_codes.device_code
            )

            if error and error.message == "authorization_pending":
                # If the authorization is pending, try again.
                continue
            elif error and error.message == "expired_token":
                # If the pairing codes have expired, break to generate new codes.
                break
            elif error:
                # If there was some other error, raise it.
                raise error
            else:
                # If there was no error, we have our authorization!
                return authorization

        # If we get here, our pairing codes expired. Let's try again.
        print("\nPairing code expired. Generating a new one...")
```

**Nota:** El bucle externo gestiona casos donde los códigos de emparejamiento caducan y se requieren códigos nuevos.

Como paso final, recupere y muestre información del proyecto desde Frame.io para confirmar el emparejamiento correcto al proyecto previsto. Veremos esto en el próximo tutorial.





## Cómo crear y mostrar códigos QR para el emparejamiento

Al implementar el emparejamiento con código URL/QR, necesitará generar un código QR a partir del valor del `verification_uri_complete` en la respuesta. A continuación, se muestran algunos ejemplos que utilizan bibliotecas populares en diferentes lenguajes de programación:

### Ejemplo de Python con qrcode





**`Python`**

```python title="Python"
import qrcode
from PIL import Image
import io

def generate_qr_code(verification_uri_complete, size=250):
    """
    Generate a QR code from the verification_uri_complete URL.
    
    Args:
        verification_uri_complete (str): The complete verification URI returned by Frame.io
        size (int, optional): Size of the QR code in pixels. Defaults to 250.
    
    Returns:
        PIL.Image: QR code image that can be displayed or saved
    """
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=10,
        border=4,
    )
    qr.add_data(verification_uri_complete)
    qr.make(fit=True)
    
    img = qr.make_image(fill_color="black", back_color="white")
    
    # Resize the image if needed
    img = img.resize((size, size))
    return img

# Example usage in authorization flow
def display_qr_for_pairing(pairing_codes):
    """
    Generate and display QR code along with manual pairing instructions.
    """
    if hasattr(pairing_codes, 'verification_uri_complete'):
        # Generate QR code from the verification URI
        qr_img = generate_qr_code(pairing_codes.verification_uri_complete)
        
        # Display the QR code on screen
        # For GUI applications like Tkinter, PyQt, etc.
        # display_image(qr_img)
        
        # For headless devices or testing, save to file
        qr_img.save("frame_io_pairing_qr.png")
        
        print(f"Scan the QR code or visit: {pairing_codes.verification_uri}")
        print(f"Manual code: {pairing_codes.user_code}")
    else:
        # Fallback for devices that received traditional pairing response
        print(f"Enter code on Frame.io: {pairing_codes.user_code}")
```





### Ejemplo de JavaScript (web o Electron)





```javascript
import QRCode from 'qrcode';

/**
 * Generate and display a QR code from the verification URI
 * @param {string} verificationUriComplete - The complete verification URI from Frame.io
 * @param {string} elementId - ID of the HTML element to display the QR code in
 */
function displayQRCode(verificationUriComplete, elementId = 'qrcode-container') {
  const element = document.getElementById(elementId);
  
  if (!element) {
    console.error(`Element with ID ${elementId} not found`);
    return;
  }
  
  // Clear any existing content
  element.innerHTML = '';
  
  // Generate QR code
  QRCode.toCanvas(element, verificationUriComplete, { width: 250 }, function(error) {
    if (error) {
      console.error('Error generating QR code:', error);
      // Fallback to displaying the URL as a link
      element.innerHTML = `<a href="${verificationUriComplete}" target="_blank">Click here to pair</a>`;
    }
  });
  
  // Also display manual pairing information
  const manualInfoDiv = document.createElement('div');
  manualInfoDiv.innerHTML = `
    <p>Scan the QR code or <a href="${verificationUriComplete}" target="_blank">click here</a> to pair your device.</p>
    <p>Manual code: ${userCode}</p>
  `;
  element.parentNode.appendChild(manualInfoDiv);
}

// Example usage in authorization flow
async function requestDeviceCode() {
  try {
    const response = await fetch('https://api.frame.io/v2/auth/device/code', {
      method: 'POST',
      headers: {
        'x-client-version': '2.0.0',
        'x-client-platypus-enabled': 'true'
      },
      body: new URLSearchParams({
        'client_id': YOUR_CLIENT_ID,
        'client_secret': YOUR_CLIENT_SECRET,
        'scope': 'asset_create offline'
      })
    });
    
    const data = await response.json();
    
    if (data.verification_uri_complete) {
      displayQRCode(data.verification_uri_complete);
      window.userCode = data.user_code; // Store for display purposes
    } else {
      // Fallback for traditional pairing
      displayManualPairingCode(data.user_code);
    }
    
    // Begin polling for authorization
    beginPollingForAuthorization(data.device_code, data.interval);
    
  } catch (error) {
    console.error('Error requesting device code:', error);
  }
}
```





### Ejemplo de Android (Java)





```java
import android.graphics.Bitmap;
import android.widget.ImageView;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.journeyapps.barcodescanner.BarcodeEncoder;

public void generateAndDisplayQRCode(String verificationUriComplete, ImageView qrCodeImageView) {
    try {
        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
        BitMatrix bitMatrix = multiFormatWriter.encode(verificationUriComplete, 
            BarcodeFormat.QR_CODE, 250, 250);
        BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
        Bitmap bitmap = barcodeEncoder.createBitmap(bitMatrix);
        
        // Display in ImageView
        qrCodeImageView.setImageBitmap(bitmap);
        
    } catch (Exception e) {
        e.printStackTrace();
        // Fallback to displaying the URL as text
    }
}
```





### Ejemplo de iOS (Swift)





```swift
import UIKit
import CoreImage

func generateQRCode(from string: String) -> UIImage? {
    let data = string.data(using: String.Encoding.utf8)
    
    if let filter = CIFilter(name: "CIQRCodeGenerator") {
        filter.setValue(data, forKey: "inputMessage")
        filter.setValue("H", forKey: "inputCorrectionLevel")
        
        if let outputImage = filter.outputImage {
            // Scale the image
            let transform = CGAffineTransform(scaleX: 10, y: 10)
            let scaledImage = outputImage.transformed(by: transform)
            
            // Convert to UIImage
            let context = CIContext()
            if let cgImage = context.createCGImage(scaledImage, from: scaledImage.extent) {
                return UIImage(cgImage: cgImage)
            }
        }
    }
    
    return nil
}

// Usage in your view controller
func displayPairingQRCode(verificationUriComplete: String) {
    if let qrCodeImage = generateQRCode(from: verificationUriComplete) {
        qrCodeImageView.image = qrCodeImage
        
        // Also show manual pairing information
        pairingInstructionsLabel.text = "Scan the QR code or enter code manually"
        pairingCodeLabel.text = userCode
    } else {
        // Fallback to manual code display
        pairingInstructionsLabel.text = "Enter this code on Frame.io:"
        pairingCodeLabel.text = userCode
    }
}
```





## Prácticas recomendadas para mostrar códigos QR





Al implementar el emparejamiento con código QR, tenga en cuenta estas directrices para obtener la mejor experiencia del usuario:




1. **Tamaño óptimo**: Muestre códigos QR de al menos 200-250 píxeles cuadrados para un escaneo fiable.




2. **Contraste**: Asegúrese de que haya un alto contraste entre el código QR y el fondo (negro sobre blanco es lo ideal).




3. **Corrección de errores**: Use niveles de corrección de errores moderados (L o M) para equilibrar la densidad y la fiabilidad del código.




4. **Instrucciones claras**: Proporcione una orientación clara sobre cómo escanear el código, como &quot;Escanee este código con la cámara de su smartphone para emparejar su dispositivo.&quot;




5. **Varias opciones**: Proporcione siempre el código de emparejamiento manual junto con el código QR como opción de reserva:


   

```
   Scan to pair:
   [QR CODE]
   
   Or enter code manually: 573131
```




6. **Hipervínculo para aplicaciones móviles**: Si su integración es una aplicación móvil, incluya el `verification_uri_complete` como un vínculo en el que se puede pulsar, ya que los usuarios no pueden escanear un código QR desde el mismo dispositivo.




7. **Pruebas**: Pruebe sus códigos QR con varios dispositivos y condiciones de iluminación para garantizar un escaneo fiable.

![Ejemplo de cómo se muestra un código QR](/_fern-img/193d938af906dbcbc9699953e9da5ddbeeee8cd75fdfabf0661127c2b528cdb4.webp)

## Solución de problemas





Si surgen problemas, consulte estos escenarios comunes y sus soluciones:




* **Botón &quot;Dispositivo conectado&quot; no visible**: Al acceder al panel de administración de C2C, esto podría indicar:

* **Permisos insuficientes**: Si ve un mensaje sobre permisos, póngase en contacto con su administrador de cuentas para ajustar los permisos o asignar una función apropiada. * **Conexión de dispositivo existente**: Después de conectar un dispositivo, el botón principal &quot;Añadir dispositivo nuevo&quot; se reemplaza por un menú de tres puntos situado en la esquina superior derecha del panel Conexiones de C2C.
* **Error de cliente no válido**: Una respuesta `invalid_client` indica una discrepancia en la información del dispositivo, generalmente debido a un `client_secret` incorrecto.
* **Error de solicitud incorrecta**: Una respuesta `bad_request` indica que los datos de la solicitud tienen un formato incorrecto. Verifique los nombres de los campos y asegúrese de que todos los campos obligatorios estén incluidos.




Si su problema no aparece aquí, comparta su experiencia para que podamos mejorar esta sección de solución de problemas.





## Próximos pasos

Le recomendamos que se ponga en contacto con nuestro equipo y que luego continúe con la [guía Administración de autorizaciones](./how-to-authorization-management). Quedamos a la espera de recibir sus comentarios.