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

# Présentation de la liaison sociale

> Comment vos utilisateurs connectent leurs comptes sociaux — les trois surfaces, la session de liaison qui les sous-tend toutes, et les options qu'elles partagent.

export const PlansAvailable = ({plans = [], maxPackRequired}) => {
  let displayPlans = plans;
  if (plans && plans.length === 1) {
    const lowerCasePlan = plans[0].toLowerCase();
    if (lowerCasePlan === "business") {
      displayPlans = ["Launch", "Business", "Enterprise"];
    } else if (lowerCasePlan === "premium") {
      displayPlans = ["Premium", "Launch", "Business", "Enterprise"];
    }
  }
  return <Note>
Available on {displayPlans.length === 1 ? "the " : ""}
{displayPlans.join(", ").replace(/\b\w/g, l => l.toUpperCase())}{" "}
{displayPlans.length > 1 ? "plans" : "plan"}.

{maxPackRequired && <span onClick={() => window.open('https://www.ayrshare.com/docs/additional/maxpack', '_self')} className="flex items-center mt-2 cursor-pointer">
 <span className="px-1.5 py-0.5 rounded text-sm" style={{
    backgroundColor: '#C264B6',
    color: 'white',
    fontSize: '12px'
  }}>
   Max Pack required
 </span>
</span>}
</Note>;
};

<PlansAvailable plans={["business"]} maxPackRequired={false} />

Vos utilisateurs connectent eux-mêmes leurs propres comptes sociaux — ils s'authentifient
directement auprès de chaque réseau, et vous ne voyez ni ne stockez jamais leurs identifiants. Tout
sur cette page consiste à les amener jusqu'à ce moment et à savoir comment cela s'est passé.

Une chose est commune à toutes les voies : une **session de liaison**, créée avec
[Créer une session de liaison](/docs/apis/profiles/create-link-session) à partir de votre clé API et d'une `Profile-Key`.
Rien n'est signé de votre côté et aucune clé privée n'intervient dans le flux.

## Trois façons de connecter

Trois formes, et les deux premières sont la même intégration. Choisissez par flux — elles ne sont
pas exclusives, et beaucoup d'intégrations utilisent la page hébergée pour l'onboarding et le widget
dans l'application ensuite.

| Surface                                                                                                                         | Votre utilisateur voit                                                                               | Marque blanche                                                                                       | Choisissez-la quand                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| **Widget — frames intégrées** ([mount](/docs/multiple-users/connect-widget#mount-a-slot))                                            | nos boutons directement dans votre propre mise en page ; aucune popup avant celle du réseau lui-même | **La plus forte.** Votre page, vos polices et vos couleurs, et votre utilisateur ne la quitte jamais | vous avez un tableau de bord avec une ligne par réseau et voulez que la liaison se fasse sur place. Max Pack. |
| **Widget — votre propre bouton** ([popup](/docs/multiple-users/connect-widget#your-own-button))                                      | votre bouton, puis une seule popup pour le réseau                                                    | **Forte.** La popup est la nôtre, mais elle est brève et hérite de votre apparence                   | vous voulez votre propre bouton et votre propre style, et aucune frame dans votre mise en page. Max Pack.     |
| **Page de liaison hébergée** ([mode d'emploi](/docs/multiple-users/api-integration-business#single-sign-on-with-jwt-authentication)) | une page que nous hébergeons, portant votre logo, vos couleurs et votre CSS personnalisé             | **La plus faible.** C'est notre page, et votre utilisateur quitte la vôtre pour l'utiliser           | vous voulez un lien unique à distribuer, ou vous intégrez par e-mail. Rien à construire, pas de Max Pack.     |

<Note>
  Les deux lignes du widget sont **une seule intégration**, pas deux. Un seul `init` vous donne les
  deux : montez des frames là où vous voulez nos boutons, et appelez `popup()` depuis votre propre
  bouton partout ailleurs. Elles partagent une même session et rapportent sur les mêmes handlers.

  Le [mode direct](/docs/multiple-users/connect-direct-mode) est la même popup **sans** notre script —
  pour une page avec une Content-Security-Policy stricte, une page rendue côté serveur ou une
  application native. Là, c'est vous qui ouvrez et surveillez la popup.

  **Vous hésitez ?** Commencez par la page de liaison hébergée. Elle ne nécessite ni Max Pack ni
  paramètres supplémentaires, et c'est la voie la plus rapide vers quelque chose qui fonctionne —
  passer au widget plus tard ne change pas la manière dont les sessions sont créées.
</Note>

## Créer un lien

Appelez [Créer une session de liaison](/docs/apis/profiles/create-link-session) avec la `Profile-Key`
de l'utilisateur dans l'en-tête. Pour la page hébergée, c'est là toute la requête :

```bash cURL theme={"system"}
curl -X POST https://api.ayrshare.com/api/profiles/link-sessions \
  -H "Authorization: Bearer $AYRSHARE_API_KEY" \
  -H "Profile-Key: $PROFILE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

Vous recevez en retour une `url` portant un token opaque de courte durée :

```javascript Linking URL theme={"system"}
https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=YOUR_DOMAIN
```

Vous pouvez également [vérifier si un lien a été ouvert](/docs/apis/profiles/get-link-session) et le
[révoquer](/docs/apis/profiles/revoke-link-session) avant son expiration.

<Note>
  Cette vidéo d'une minute montre comment créer un lien. Elle a été enregistrée avant les sessions
  de liaison, donc elle montre encore l'envoi d'une Private Key — cette étape n'est plus nécessaire,
  et tout le reste de ce qu'elle montre est inchangé.

  <div class="video-container">
    <iframe width="380" height="200" src="https://www.youtube.com/embed/JI232HBWHWc" title="Create a linking URL" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" />
  </div>
</Note>

<h3 id="sending-the-linking-url">
  Envoyer l'URL de liaison
</h3>

<Warning>
  Une URL de liaison connecte votre utilisateur à son profil : traitez-la comme un mot de passe.
  Transmettez-la par un canal de confiance, ne la journalisez pas et ne la communiquez pas à un
  tiers. Elle reste utilisable pendant toute sa fenêtre, donc un rechargement ou une nouvelle
  tentative OAuth fonctionne — mais n'envoyez chaque lien qu'à un seul utilisateur et créez un
  lien distinct par personne.
</Warning>

### Ouverture de l'URL de liaison

Ouvrez-la dans un nouvel onglet, une nouvelle fenêtre de navigateur ou un View Controller. Vous
pouvez contrôler la
[fermeture ou la redirection](/docs/multiple-users/api-integration-business#opening-and-closing-the-social-linking-url)
de cette fenêtre.

<Note>
  Les réseaux sociaux ne permettent pas d'ouvrir la page de liaison hébergée dans une iFrame, ni de
  masquer l'origine du partenaire approuvé `profile.ayrshare.com`. Si vous voulez que la liaison se
  fasse à l'intérieur de votre propre page, c'est précisément le rôle du
  [widget intégré](/docs/multiple-users/connect-widget) : ses frames sont servies depuis une origine
  Ayrshare et constituent la manière prise en charge de le faire.
</Note>

### Savoir quand c'est terminé

Deux signaux, et vous pouvez utiliser l'un ou l'autre :

* **[Événements de fin de liaison](/docs/multiple-users/link-completion-events)** — définissez un
  `origin` lorsque vous créez le lien et la fenêtre de liaison poste `connect:success`,
  `connect:error` et `connect:cancelled` à votre page au fil des événements. Aucun polling.
* **[Obtenir une session de liaison](/docs/apis/profiles/get-link-session)** — rapporte `completedAt`,
  `lastCompletedAt` et `completedNetworks`. C'est le signal pour les applications natives, et le
  seul pour Telegram, qui se termine hors bande.

<h2 id="jwt-expires-in">
  Expiration du lien
</h2>

Un lien est valide pendant **5 minutes** par défaut. Passé ce délai, créez-en un nouveau.

<PlansAvailable plans={["business"]} maxPackRequired />

Avec le Max Pack, définissez `expiresIn` en minutes pour élargir cette fenêtre — jusqu'à **2880
minutes (48 heures)**, qui est le maximum accepté par l'API :

```json Expires In theme={"system"}
{
  "expiresIn": 30
}
```

Une fenêtre plus longue est ce qui rend l'[envoi du lien par e-mail](#connect-accounts-email)
praticable — un utilisateur qui reconnecte un compte perdu peut aller directement de votre e-mail
au réseau, sans passer d'abord par votre application.

<Warning>
  Vérifiez avec votre équipe de sécurité combien de temps un lien doit rester actif. Une fenêtre
  plus longue, c'est une période plus longue pendant laquelle un lien intercepté fonctionne encore.
  Si un lien s'échappe, vous pouvez le [révoquer](/docs/apis/profiles/revoke-link-session) plutôt que
  d'attendre son expiration.
</Warning>

## Profile Key

La `Profile-Key` indique à quel User Profile le lien correspond. Vous la trouverez dans le tableau
de bord développeur Ayrshare en basculant sur ce profil.

<Note>
  **La Private Key n'est plus utilisée.** Les liens ne sont pas signés : il n'y a donc rien à lire
  depuis un fichier ni à coller dans votre code. Le paramètre historique `privateKey` est toujours
  accepté et ignoré, donc les intégrations existantes continuent de fonctionner, et le fichier
  `private.key` de votre Integration Package peut rester inutilisé.
</Note>

## Basculement entre les profils

Si un profil est déjà connecté, ouvrir le lien d'un autre profil ne change pas de profil — c'est
délibéré, et cela rend l'expérience plus rapide pour un utilisateur déjà présent. Pour forcer un
basculement, consultez
[Déconnexion automatique d'une session de profil](/docs/multiple-users/api-integration-business#automatic-logout-of-a-profile-session).

<h2 id="instagram-link-method">
  Méthode de liaison Instagram
</h2>

Les comptes Instagram peuvent être liés de [deux manières](/docs/dashboard/connect-social-accounts/instagram) :
directement avec **Instagram Login**, ou via une **page Facebook connectée**. Le flux qui démarre
lorsqu'un utilisateur clique sur le bouton Instagram est normalement contrôlé par le paramètre à
l'échelle du compte [Instagram Login](/docs/multiple-users/manage-user-profiles#instagram-login).

Le paramètre de corps `instagramLinkMethod` remplace ce paramètre pour un seul lien :

| Valeur      | Flux de liaison Instagram                             |
| ----------- | ----------------------------------------------------- |
| `instagram` | Instagram Login direct. Aucune page Facebook requise. |
| `facebook`  | Lien via une page Facebook connectée.                 |

```json Instagram Link Method theme={"system"}
{
  "instagramLinkMethod": "instagram"
}
```

Le remplacement s'applique pendant toute la durée de vie de ce lien, y compris à travers la
redirection d'autorisation Instagram/Facebook. Quelques points à savoir :

* Il ne modifie pas votre paramètre à l'échelle du compte ni n'affecte les autres liens.
* Omettez-le et le paramètre à l'échelle du compte s'applique, exactement comme avant.
* Une valeur invalide retourne `400` listant les valeurs valides (`instagram`, `facebook`).
* Passez en revue les
  [différences de fonctionnalités](/docs/multiple-users/manage-user-profiles#direct-instagram-login-vs-facebook-page-authentication)
  avant de choisir — certaines fonctionnalités Instagram, telles que la recherche de hashtags et
  les collaborations, ne sont disponibles qu'avec l'authentification via page Facebook.

<h2 id="connect-accounts-email">
  E-mail Connect Accounts
</h2>

<PlansAvailable plans={["business"]} maxPackRequired />

Ayrshare peut envoyer le lien par e-mail à votre utilisateur pour vous, afin qu'il puisse accéder
à sa page de liaison sans passer par votre application. Associez cela à un
[`expiresIn`](#jwt-expires-in) plus long — les cinq minutes par défaut survivent rarement à une
boîte de réception.

### JSON Connect Accounts

**Chaque champ à l'intérieur de `email` est requis.** Un champ manquant fait échouer l'envoi.

```json Example Contact Email Request theme={"system"}
{
  "expiresIn": 60,
  "email": {
    "to": "john@user.com",
    "contactEmail": "support@mycompany.com",
    "company": "ACME",
    "termsUrl": "https://www.ayrshare.com/terms",
    "privacyUrl": "https://www.ayrshare.com/privacy"
  }
}
```

<Warning>
  `expiresIn` est un paramètre de **premier niveau**, pas une partie de l'objet `email`. Imbriqué
  dans `email`, il est ignoré, et votre utilisateur reçoit un lien qui expire au bout de cinq
  minutes.
</Warning>

La réponse indique le résultat dans `emailSent` :

```json Example Contact Email Response theme={"system"}
{
  "status": "success",
  "sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8",
  "url": "https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=YOUR_DOMAIN",
  "expiresAt": "2026-09-02T09:03:26.838Z",
  "emailSent": true,
  "title": "Acme Client"
}
```

Un **échec** d'envoi ne revient pas sous la forme `emailSent: false` — il retourne `code: 333` à la
place. Ainsi, `false` signifie qu'aucun e-mail n'a été demandé.

### Exemple d'e-mail Connect Accounts

Voici un exemple de l'e-mail qui ouvre la page de liaison sociale :

<img src="https://mintcdn.com/ayrshare-docs/Nmrhj2Gh7WSf62Bh/images/apis/profiles/jwt-email.webp?fit=max&auto=format&n=Nmrhj2Gh7WSf62Bh&q=85&s=fbe4ee86ca59c26a5bd5b289fda96b8b" alt="Connect Accounts email" width="563" class="center" data-path="images/apis/profiles/jwt-email.webp" />

L'e-mail provient de l'adresse :

`Social Connect Hub <connect@socialconnecthub.com>`

<h2 id="mobile-jwt">
  Applications mobiles
</h2>

Ouvrez l'URL de liaison dans le **navigateur système**, jamais dans une webview intégrée : Google
rejette la connexion dans une webview avec `disallowed_useragent`, et Meta la bloque purement et
simplement. Votre utilisateur verrait la page d'erreur du réseau lui-même, et rien de votre côté ne
peut y remédier.

* **iOS** — `ASWebAuthenticationSession`, ou `SFSafariViewController`.
* **Android** — Chrome Custom Tabs.

Comme une application native n'a pas de fenêtre de navigateur à laquelle poster des événements,
récupérez le résultat depuis [Obtenir une session de liaison](/docs/apis/profiles/get-link-session) à la
place. Définissez `origin` sur votre schéma personnalisé (`myapp://connected`) pour que la page ait
un moyen de revenir dans votre application.

<h3 id="mobile-code-examples">
  Exemples de code mobile
</h3>

Remplacez `linkingURL` par l'`url` renvoyée par
[Créer une session de liaison](/docs/apis/profiles/create-link-session).

<CodeGroup>
  ```swift Swift theme={"system"}
  import UIKit
  import SafariServices

  class ViewController: UIViewController, SFSafariViewControllerDelegate {

      var linkingURL = "https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=acme"

      override func viewDidLoad() {
          super.viewDidLoad()
          setupButton()
      }

      func setupButton() {
          let button = UIButton(type: .system)
          button.frame = CGRect(x: (view.bounds.width - 200) / 2, y: (view.bounds.height - 50) / 2, width: 200, height: 50)
          button.setTitle("Open URL", for: .normal)
          button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
          view.addSubview(button)
      }

      @objc func buttonTapped() {
          openURLInInAppBrowser()
      }

      func openURLInInAppBrowser() {
          if let url = URL(string: linkingURL) {
              let safariVC = SFSafariViewController(url: url)
              safariVC.delegate = self
              present(safariVC, animated: true, completion: nil)
          }
      }

      // Optional: If you want to handle when the in-app browser is closed
      func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
          controller.dismiss(animated: true, completion: nil)
      }
  }
  ```

  ```dart Flutter theme={"system"}
  /** yaml dependencies
    dependencies:
      flutter:
        sdk: flutter
      url_launcher: ^6.2.1
  */

  import 'package:flutter/material.dart';
  import 'package:url_launcher/url_launcher.dart';

  void main() {
    runApp(MyApp());
  }

  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'URL Launcher Example',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(),
      );
    }
  }

  class MyHomePage extends StatelessWidget {
    final String linkingURL = "https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=acme";

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text('URL Launcher Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              openURLInBrowser(context);
            },
            child: Text('Open URL'),
          ),
        ),
      );
    }

    void openURLInBrowser(BuildContext context) async {
      if (await canLaunch(linkingURL)) {
        await launch(linkingURL);
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Could not launch $linkingURL'),
          ),
        );
      }
    }
  }
  ```

  ```jsx React Native theme={"system"}
  /**
  • Using the API provided by expo-web-browser,
  • which opens a URL in a modal browser window that shares cookies
  • with the system browser.

  • Learn more about expo: https://reactnative.dev/docs/environment-setup?guide=quickstart
  • and running the following command:
  • expo install expo-web-browser
  */

  import React from 'react';
  import { StyleSheet, Button, View } from 'react-native';
  import * as WebBrowser from 'expo-web-browser';

  export default function App() {
    const linkingURL = 'https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=acme';

    const openURLInBrowser = async () => {
      try {
        await WebBrowser.openBrowserAsync(linkingURL);
        // Optional: WebBrowser.openBrowserAsync returns a promise that resolves with an object containing
        // 'type' that can be 'cancelled' or 'dismissed'. You can use this to handle when the browser is closed.
      } catch (error) {
        console.error(error);
      }
    };

    return (
      <View style={styles.container}>
        <Button title="Open URL" onPress={openURLInBrowser} />
      </View>
    );
  }

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
    },
  });
  ```
</CodeGroup>

## Tests

Il est **recommandé** de d'abord créer un lien dans [Postman](/docs/testing/postman). Votre Integration
Package — sur la page API Key du Primary Profile dans le tableau de bord — inclut un exemple de
configuration Postman. Importez-le, renseignez votre Profile Key dans le champ *body* `profileKey`,
puis cliquez sur *Send*.

La configuration d'exemple préremplit toujours `privateKey` et `domain`. `privateKey` est ignoré,
et vous pouvez vider `domain` sauf si votre compte possède plusieurs domaines de liaison.

Vous pouvez aussi [générer le code depuis Postman](/docs/testing/postman#auto-generate-api-code-with-postman).

### Bubble.io

<Card title="Bubble linking URL" icon="link" href="/docs/packages-guides/bubble#generate-a-linking-url-in-bubble" horizontal />

## Historique : generateJWT

<Info>
  [Générer une URL de liaison](/docs/apis/profiles/generate-jwt) (`generateJWT`) réalise la même
  opération et est **déprécié** — entièrement pris en charge, sans date de retrait, et inchangé
  pour les liens que vous avez déjà distribués. Sa propre page documente ses paramètres, y compris
  les trois qui sont désormais acceptés et ignorés.

  Les deux endpoints utilisent le même validateur, donc tout ce qui figure sur cette page
  s'applique à l'un comme à l'autre. La seule différence à connaître lors de votre migration :
  `generateJWT` tolère trois choses que Créer une session de liaison rejette — un réseau
  `allowedSocial` inconnu, un identifiant X isolé, et un `redirect` non textuel.
</Info>
