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

# Comment octroyer des autorisations

## Présentation





Ce guide présente le processus d’authentification et d’autorisation pour les appareils Camera to Cloud (C2C) sur un projet Frame.io. Nous explorerons à la fois la méthode standard de saisie manuelle de code et l’approche améliorée de couplage par code QR pour une expérience client optimale.





## De quoi ai-je besoin ?

Si ce n’est pas déjà fait, consultez le guide [Avant de commencer l’implémentation](./implementing-c2c-setting-up). Vous devriez avoir reçu une valeur `client_secret` de notre équipe pour identifier votre intégration. Si ce n’est pas le cas, consultez [cette introduction](./getting-started-with-cloud-device-integrations) au réseau C2C et contactez notre équipe.

### Conditions préalables pour le couplage par URL et code QR





Pour mettre en œuvre le couplage par URL et code QR, vérifiez que vous respectez les exigences suivantes :





* **Compatibilité de l’appareil** : vérifiez que l’appareil prend en charge la génération d’URL/code QR pendant le processus de couplage.




## Exploration du flux d’autorisation





Pour comprendre le flux d’autorisation du point de vue de l’utilisateur, consultez ces ressources :




* [Article d’aide](https://help.frame.io/fr/collections/8960335-frame-io-c2c) pour ajouter de nouveaux appareils.
* [Vidéo de formation](https://help.frame.io/fr/articles/5091124-camera-to-cloud-training-series) sur l’autorisation d’un Teradek Cube.




Ce processus d’autorisation minimise les exigences d’implémentation. Vous n’aurez pas besoin de :




* rediriger vers les navigateurs web (sauf lors du couplage par code URL) ;
* gérer l’authentification de l’utilisateur Frame.io ;
* présenter les interfaces de sélection de compte/projet ;
* développer des composants d’interface utilisateur complexes au-delà des affichages d’informations de base.




### Amélioration de l’expérience client avec le couplage par code URL





Les utilisateurs modernes s’attendent à des interactions efficaces avec les appareils. Bien que le processus de couplage manuel actuel fonctionne correctement, il peut être optimisé.





En implémentant le couplage par URL et code QR (semblable aux services de streaming comme Netflix ou Disney+), nous pouvons considérablement rationaliser le processus, minimiser les erreurs de saisie et raccourcir le temps de couplage.





## Identification de l’appareil (client_id)





Chaque appareil physique nécessite un identifiant unique pour le suivi des connexions dans le projet d’un utilisateur.

Pour les appareils, cet identifiant correspond au paramètre `client_id`, qui est essentiel lors de l’autorisation. Lors de l’implémentation, considérez des sources d’identifiants appropriées telles que les numéros de série d’appareil, les UUID ou d’autres chaînes uniques. Si vous effectuez l’intégration sur un appareil Apple, nous vous recommandons d’utiliser un UUID persistant unique qui reste cohérent lors des redémarrages de l’appareil. Faites preuve de prudence concernant les informations personnellement identifiables. Les adresses e-mail des utilisateurs ne sont pas des valeurs `client_id` appropriées.

Assurez-vous également de contrôler l’identifiant. Les adresses MAC des appareils ne conviennent pas, car elles n’appartiennent pas à votre logiciel et peuvent constituer des informations personnellement identifiables.





Si vous avez besoin de conseils pour choisir un identifiant approprié, notre équipe peut vous aider à déterminer une valeur adaptée qui simplifie l’intégration.





## Étape 1 : demande d’un code d’appareil

Pour commencer l’implémentation, demandez un code d’appareil via le point d’entrée `/v2/auth/device/code` :

### Méthode de couplage traditionnelle





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





### Activation du couplage par code URL





Pour le couplage par code URL, modifiez l’appel API avec des en-têtes supplémentaires :





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

**Remarque :** ces points d’entrée d’authentification acceptent exclusivement les données de formulaire, pas JSON. Après l’authentification, les autres points d’entrée accepteront les payloads JSON, mais les points d’entrée d’authentification rejetteront les requêtes JSON.

#### Paramètres de payload




* **client_id** : identifiant unique pour votre appareil physique. Il doit absolument être unique, par exemple un numéro de série ou UUID.
* **client_secret** : fourni par le support Frame.io pour identifier votre modèle d’appareil. Cette valeur confidentielle doit rester protégée des utilisateurs et chiffrée lors du stockage.
* **scope** : autorisations demandées, séparées par des espaces. Les appareils peuvent demander :

* `asset_create` : active la création et le chargement de ressources. * `offline` : permet l’actualisation de l’autorisation via le jeton d’actualisation. Sans cette portée, les utilisateurs devraient réautoriser leur appareil toutes les 8 heures, car les jetons d’autorisation expirent.

Dans les implémentations pratiques, les appareils demandent généralement les deux portées.





### Comprendre la réponse de l’API





La demande génère une réponse semblable à :





#### Réponse de couplage traditionnel





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





#### Réponse de couplage par 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"
}
```





#### Décomposition de la réponse




* **device_code** : cet identifiant interne ne doit pas être visible pour les utilisateurs ; il identifie la demande d’autorisation lors de l’enquête.
* **expires_in** : période de validité du code en secondes.
* **interval** : intervalle d’enquête recommandé en secondes.
* **name** : identifiant de l’appareil de connexion.
* **user_code** : code à six chiffres pour la saisie manuelle dans Frame.io pour le couplage de l’appareil.
* **verification_uri** : URL de base pour la saisie manuelle s’il est impossible de scanner le code QR.
* **verification_uri_complete** : URL complète contenant le code de couplage, destinée aux liens hypertexte dans une application mobile ou à la génération de code QR pour simplifier la navigation utilisateur vers l’interface de couplage.




### Affichage du code QR pour l’utilisateur

En utilisant `verification_uri_complete`, générez et affichez un code QR sur l’écran de l’appareil pour que l’utilisateur puisse le scanner, facilitant ainsi un couplage efficace.

#### Exemple : écran d’appareil avec code QR affiché

![Exemple d’écran de couplage par code QR](/_fern-img/193d938af906dbcbc9699953e9da5ddbeeee8cd75fdfabf0661127c2b528cdb4.webp) Fournissez toujours des options de secours : affichez les paramètres `user_code` et `verification_uri` pour la saisie manuelle lorsque le code QR ne peut pas être scanné. Vous pouvez également afficher le paramètre `verification_uri` comme un code QR statique pour la numérisation mobile. Pour les intégrations d’application mobile, incluez `verification_uri_complete` comme un lien hypertexte cliquable, car les utilisateurs ne peuvent pas scanner les codes QR depuis l’appareil exécutant l’application.

## Étape 2 : demande d’autorisation utilisateur





Après avoir fourni le code de couplage ou le code URL, vérifiez la saisie utilisateur avec cette requête :





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





### Paramètres de payload




* **client_id** : même identifiant que celui utilisé à l’étape 1.
* **device_code** : valeur `device_code` renvoyée précédemment.
* **grant_type** : identifiant de type d’octroi OAuth, toujours `urn:ietf:params:oauth:grant-type:device_code` pour cette implémentation.




Les tentatives d’enquête initiales renvoient généralement :





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





Cette erreur non fatale indique que l’utilisateur n’a pas terminé la saisie du code. Continuez l’enquête jusqu’à la fin.



<blockquote>**Remarque pour les appareils iOS :** si l’utilisateur bascule vers l’application iOS Frame.io pour saisir le code de couplage, l’application peut passer en arrière-plan. Lorsque l’application redevient active, par exemple dans `applicationDidBecomeActive`, reprenez l’enquête pour que le flux d’autorisation puisse continuer sans que l’utilisateur ait besoin de redémarrer le couplage.</blockquote>



Si vous recevez :





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





Le code a expiré avant la saisie utilisateur. Générez un nouveau code/code QR via l’étape 1, présentez-le à l’utilisateur et reprenez l’enquête.





Une autorisation réussie produit :





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





Votre appareil Camera to Cloud a bien été autorisé !





Examinons cette réponse :




* **access_token** : vos informations d’identification d’authentification pour l’accès au backend Frame.io, requis dans les en-têtes pour les futures requêtes API.
* **expires_in** : la période de validité du jeton d’accès en secondes, après laquelle l’actualisation est nécessaire.
* **refresh_token** : utilisé pour la gestion des jetons d’accès, principalement pour actualiser l’autorisation mais aussi applicable pour la révocation.
* **token_type** : toujours `bearer` pour les implémentations d’API C2C, ne nécessitant aucune action.




## Regrouper toutes les étapes





Implémentons maintenant ces appels API en pseudocode de type Python, en gérant l’expiration potentielle du code d’appareil :





**`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...")
```

**Remarque :** la boucle externe gère les cas où les codes de couplage expirent et où de nouveaux codes sont requis.

Comme étape finale, récupérez et affichez les informations de projet depuis Frame.io pour confirmer le couplage réussi au projet prévu. Nous aborderons ce point dans le tutoriel suivant.





## Création et affichage de codes QR pour le couplage

Lors de l’implémentation du couplage URL/code QR, vous devez générer un code QR à partir de la valeur `verification_uri_complete` dans la réponse. Voici des exemples utilisant des bibliothèques populaires dans différents langages de programmation :

### Exemple Python avec 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}")
```





### Exemple 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);
  }
}
```





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





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





## Bonnes pratiques pour l’affichage de codes QR





Lors de l’implémentation du couplage par code QR, tenez compte de ces recommandations pour une expérience client optimale :




1. **Taille optimale** : affichez des codes QR d’au moins 200-250 pixels carrés pour une lecture fiable.




2. **Contraste** : assurez-vous d’un contraste élevé entre le code QR et l’arrière-plan (noir sur blanc est idéal).




3. **Correction d’erreurs** : utilisez des niveaux de correction d’erreurs modérés (L ou M) afin de trouver un juste équilibre entre la densité du code et sa fiabilité.




4. **Instructions claires** : fournissez des instructions claires sur la façon de scanner le code, par exemple « Scannez ce code avec l’appareil photo de votre smartphone pour coupler votre appareil. »




5. **Options multiples** : fournissez toujours le code de couplage manuel avec le code QR comme solution de secours :


   

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




6. **Lien hypertexte pour Mobile Apps** : si votre intégration est une application mobile, incluez `verification_uri_complete` comme lien cliquable, car les utilisateurs ne peuvent pas scanner un code QR depuis le même appareil.




7. **Tests** : testez les codes QR avec différents appareils et conditions d’éclairage pour assurer une lecture fiable.

![Exemple d’affichage de code QR](/_fern-img/193d938af906dbcbc9699953e9da5ddbeeee8cd75fdfabf0661127c2b528cdb4.webp)

## Résolution des problèmes





Si vous rencontrez des problèmes, consultez les scénarios courants suivants et leurs solutions :




* **Bouton « Connecter un appareil » non visible** : lors de l’accès au panneau de gestion C2C, cette erreur peut indiquer :

* **Autorisations insuffisantes** : si un message d’autorisations s’affiche, contactez le gestionnaire de compte pour ajuster les autorisations ou attribuer un rôle approprié. * **Connexion d’appareil existante** : après avoir connecté un appareil, le bouton principal « Ajouter un nouvel appareil » est remplacé par un menu à trois points dans le coin supérieur droit du panneau Connexions C2C.
* **Erreur de client non valide** : une réponse `invalid_client` indique une incompatibilité des informations de l’appareil, généralement due à un paramètre `client_secret` incorrect.
* **Erreur de demande incorrecte** : une réponse `bad_request` indique des données de demande incorrectement formées. Vérifiez les noms des champs et assurez-vous que tous les champs requis sont inclus.




Si votre problème n’est pas traité ici, partagez votre expérience afin que nous puissions améliorer cette section de résolution des problèmes.





## Étapes suivantes

Nous vous invitons à contacter notre équipe et à consulter le [guide de gestion des autorisations](./how-to-authorization-management). Nous attendons vos commentaires avec impatience !