> This page is for Camera to Cloud.

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

# Instruções: Autorizar

## Introdução





Este guia demonstra o processo de autenticação e autorização para dispositivos Camera to Cloud (C2C) em um projeto Frame.io. Vamos explorar tanto o método padrão de inserção manual de código quanto a abordagem aprimorada de emparelhamento via QR Code para otimizar a experiência do usuário.





## O que vou precisar?

Revise o guia [Antes de começar a implementação](./implementing-c2c-setting-up) se ainda não fez isso. Você deve ter recebido um `client_secret` da nossa equipe para identificar sua integração. Se não recebeu, consulte [esta introdução](./getting-started-with-cloud-device-integrations) ao ecossistema C2C e entre em contato com nossa equipe.

### Pré-requisitos para emparelhamento por URL e QR Code





Para implementar o emparelhamento por URL e QR Code, certifique-se de atender aos requisitos:





* **Compatibilidade de dispositivos**: verifique se o dispositivo suporta geração de URL/QR Code durante o processo de emparelhamento.




## Como funciona o fluxo de autorização





Para entender o fluxo de autorização da perspectiva do usuário, consulte estes recursos:




* [Artigo de suporte](https://help.frame.io/pt-BR/collections/8960335-frame-io-c2c) para adicionar novos dispositivos.
* [Vídeo de treinamento](https://help.frame.io/pt-BR/articles/5091124-camera-to-cloud-training-series) sobre como autorizar um Teradek Cube.




Este processo de autorização minimiza os requisitos de implementação. Você não precisará:




* Redirecionar para navegadores da web (a menos que use o emparelhamento por código URL)
* Lidar com autenticação de usuário do Frame.io
* Apresentar interfaces de seleção de conta/projeto
* Desenvolver componentes de interface complexos além de exibições básicas de informações




### Aprimorando a experiência do usuário com emparelhamento por URL Code





Usuários modernos esperam interações eficientes com dispositivos. Embora o processo atual de emparelhamento manual funcione adequadamente, ele pode ser otimizado.





Ao implementar o emparelhamento por URL e QR Code, semelhante aos serviços de streaming como Netflix ou Disney+, podemos simplificar significativamente o processo, minimizar erros de entrada e reduzir o tempo de emparelhamento.





## Identificação do dispositivo (client_id)





Cada dispositivo físico requer um identificador exclusivo para rastreamento de conexão dentro do projeto de um usuário.

Para dispositivos, esse identificador é o `client_id`, que é essencial durante a autorização. Ao implementar, considere origens de identificador apropriadas, como números de série do dispositivo, UUIDs ou outras strings exclusivas. Se você estiver integrando em um dispositivo Apple, recomendamos usar um UUID persistente e exclusivo que seja consistente entre reinicializações do dispositivo. Tenha cuidado com informações pessoais identificáveis. Endereços de email do usuário não são valores `client_id` adequados.

Além disso, certifique-se de controlar o identificador. Endereços MAC do dispositivo são inadequados, pois não são de propriedade do seu software e podem constituir informações pessoais identificáveis.





Se você precisar de orientação sobre como selecionar um identificador adequado, nossa equipe pode ajudar a determinar um valor adequado que simplifique a integração.





## Etapa 1: solicitar um código de dispositivo

Para começar a implementação, solicite um código de dispositivo através do ponto de acesso `/v2/auth/device/code`:

### Método de emparelhamento 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
```





### Ativação do emparelhamento por URL Code





Para emparelhamento por código URL, modifique a chamada de API com cabeçalhos adicionais:





```
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
```

**Observação:** esses pontos de acesso de autenticação aceitam exclusivamente dados de formulário, não JSON. Pós-autenticação, outros pontos de acesso aceitarão conteúdos JSON, mas pontos de acesso de autenticação rejeitarão solicitações JSON.

#### Parâmetros do conteúdo




* **client_id**: o identificador exclusivo para seu dispositivo físico. Isso deve ser garantidamente exclusivo, como um número de série ou UUID.
* **client_secret**: fornecido pelo suporte do Frame.io para identificar o modelo do seu dispositivo. Esse valor confidencial deve permanecer protegido dos usuários e criptografado quando armazenado.
* **scope**: as permissões solicitadas, separadas por espaços. Os dispositivos podem solicitar:

* `asset_create`: permite a criação e o upload de ativos. * `offline`: permite a atualização de autorização por meio do token de atualização. Sem esse escopo, os usuários precisariam autorizar novamente o dispositivo a cada 8 horas, já que os tokens de autorização expiram.

Em implementações práticas, os dispositivos normalmente solicitam ambos os escopos.





### Entender a resposta da API





A solicitação gera uma resposta similar a:





#### Resposta de emparelhamento tradicional





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





#### Resposta de emparelhamento por 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"
}
```





#### Detalhamento da resposta




* **device_code**: este identificador interno deve permanecer oculto dos usuários e identifica a solicitação de autorização durante o polling.
* **expires_in**: o período de validade do código em segundos.
* **interval**: o intervalo de polling recomendado em segundos.
* **name**: o identificador do dispositivo de conexão.
* **user_code**: o código de seis dígitos para entrada manual no Frame.io para emparelhamento do dispositivo.
* **verification_uri**: o URL base para entrada manual se a leitura do QR Code não estiver disponível.
* **verification_uri_complete**: o URL completo que contém o código de emparelhamento, destinado para criar hiperlink em um aplicativo para dispositivos móveis ou geração de QR Code para simplificar a navegação do usuário para a interface de emparelhamento.




### Exibir o QR Code para o usuário

Usando o `verification_uri_complete`, gere e exiba um QR Code na tela do dispositivo para o usuário escanear, facilitando o emparelhamento eficiente.

#### Exemplo: tela do dispositivo com QR Code exibido

![Exemplo de tela de emparelhamento de QR Code do dispositivo](/_fern-img/193d938af906dbcbc9699953e9da5ddbeeee8cd75fdfabf0661127c2b528cdb4.webp) Sempre forneça opções de fallback: exiba o `user_code` e o `verification_uri` para entrada manual quando a leitura do QR Code não for possível. Como alternativa, considere exibir o `verification_uri` como um QR Code estático para leitura móvel. Para integrações de aplicativo para dispositivos móveis, inclua o `verification_uri_complete` como um hiperlink clicável, já que os usuários não podem escanear QR Codes do dispositivo que executa o aplicativo.

## Etapa 2: polling para autorização do usuário





Depois de fornecer o código de emparelhamento ou código de URL, verifique a entrada do usuário com esta solicitação:





```
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 do conteúdo




* **client_id**: o mesmo identificador usado na Etapa 1.
* **device_code**: o valor `device_code` retornado anteriormente.
* **grant_type**: o identificador do tipo de concessão OAuth, consistentemente `urn:ietf:params:oauth:grant-type:device_code` para esta implementação.




As tentativas iniciais de polling normalmente retornam:





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





Este erro não fatal indica que o usuário não concluiu a entrada do código. Continue a enquete até a conclusão.



<blockquote>**Observação para dispositivos com app iOS:** se o usuário alternar para o app iOS do Frame.io para inserir o código de emparelhamento, o app pode ir para o fundo. Quando o app ficar ativo novamente, como em `applicationDidBecomeActive`, retome a enquete para que o fluxo de autorização possa continuar sem exigir que o usuário reinicie o emparelhamento.</blockquote>



Se receber:





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





O código expirou antes da entrada do usuário. Gere um novo código/QR Code via Etapa 1, apresente-o ao usuário e retome o polling.





A autorização bem-sucedida produz:





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





Parabéns por autorizar com sucesso o dispositivo Camera to Cloud!





Vamos analisar esta resposta:




* **access_token**: sua credencial de autenticação para acesso ao back-end do Frame.io, necessária em cabeçalhos para futuras chamadas de API.
* **expires_in**: o período de validade do token de acesso em segundos, após o qual a atualização é necessária.
* **refresh_token**: usado para gerenciamento de tokens de acesso, principalmente para atualizar autorizações, mas também aplicável para revogações.
* **token_type**: consistentemente `bearer` para implementações de API C2C, não requerendo ação.




## Reunir as etapas





Agora vamos implementar essas chamadas de API em pseudocódigo similar ao Python, lidando com potencial expiração do código do 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...")
```

**Observação:** o loop externo lida com casos onde códigos de emparelhamento expiram e novos códigos são necessários.

Como etapa final, recupere e exiba informações do projeto do Frame.io para confirmar o emparelhamento bem-sucedido ao projeto pretendido. Abordaremos isso no próximo tutorial.





## Criação e exibição de QR Codes para emparelhamento

Ao implementar o emparelhamento por URL/QR Code, você precisará gerar um QR Code a partir do valor `verification_uri_complete` na resposta. Aqui estão exemplos usando bibliotecas populares em diferentes linguagens de programação:

### Exemplo Python usando 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}")
```





### Exemplo JavaScript (Web ou 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);
  }
}
```





### Exemplo 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
    }
}
```





### Exemplo 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áticas recomendadas para exibição de QR Code





Ao implementar o emparelhamento por QR Code, considere estas diretrizes para obter a melhor experiência do usuário:




1. **Tamanho ideal**: exiba QR Codes com pelo menos 200 a 250 pixels quadrados para leitura confiável.




2. **Contraste**: garanta alto contraste entre o QR Code e o fundo (preto sobre branco é o ideal).




3. **Correção de erros**: use níveis moderados de correção de erros (L ou M) para equilibrar densidade de código e confiabilidade.




4. **Instruções claras**: forneça orientação clara sobre como escanear o código, como &quot;Escaneie este código com a câmera do smartphone para emparelhar o dispositivo&quot;.




5. **Várias opções**: sempre forneça o código de emparelhamento manual junto ao QR Code como alternativa:


   

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




6. **Hiperlink para aplicativos para dispositivos móveis**: se sua integração for um aplicativo para dispositivos móveis, inclua o `verification_uri_complete` como um link tocável, já que os usuários não conseguem escanear um QR code no mesmo dispositivo.




7. **Testar**: teste os QR Codes com vários dispositivos e condições de iluminação para garantir leitura confiável.

![Exemplo de exibição de QR Code](/_fern-img/193d938af906dbcbc9699953e9da5ddbeeee8cd75fdfabf0661127c2b528cdb4.webp)

## Solução de problemas





Se você encontrar problemas, consulte estes cenários comuns e soluções:




* **Botão &quot;Conectar dispositivo&quot; não visível**: ao acessar o painel de gerenciamento C2C, isso pode indicar:

* **Permissões insuficientes**: se você vir uma mensagem de permissões, entre em contato com o gerente de conta para ajustar as permissões ou atribuir uma função apropriada. * **Conexão de dispositivo existente**: depois de conectar um dispositivo, o botão principal &quot;Adicionar novo dispositivo&quot; é substituído por um menu de três pontos no canto superior direito do painel Conexões C2C.
* **Erro de cliente inválido**: uma resposta `invalid_client` indica incompatibilidade de informações do dispositivo, geralmente devido a um `client_secret` incorreto.
* **Erro de solicitação inválida**: uma resposta `bad_request` indica dados de solicitação inválidos.Verifique os nomes dos campos e confirme se todos os campos obrigatórios estão incluídos.




Se o problema não for resolvido aqui, compartilhe sua experiência para que possamos aprimorar esta seção de solução de problemas.





## Próximas etapas

Recomendamos que você entre em contato com nossa equipe e consulte o [guia de gerenciamento de autorizações](./how-to-authorization-management). Aguardamos seus comentários!