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

# Link Session の取得

> ソーシャル連携用 URL が開かれたか、まだ有効か、失効済みかを確認します。

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>;
};

export const HeaderAPI = ({noProfileKey, profileKeyRequired}) => <>
    <ParamField header="Authorization" type="string" required>
      <a href="/docs/apis/overview#authorization">API Key</a> of the Primary Profile.
      <br />
      <br />
      Format: <code>Authorization: Bearer API_KEY</code>
    </ParamField>
    {!noProfileKey && (profileKeyRequired ? <ParamField header="Profile-Key" type="string" required>
          <a href="/docs/apis/overview#profile-key-format">Profile Key</a> of a User Profile.
          <br />
          <br />
          Format: <code>Profile-Key: PROFILE_KEY</code>
        </ParamField> : <ParamField header="Profile-Key" type="string">
          <a href="/docs/apis/overview#profile-key-format">Profile Key</a> of a User Profile.
          <br />
          <br />
          Format: <code>Profile-Key: PROFILE_KEY</code>
        </ParamField>)}
  </>;

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

[Link Session の作成](/docs/apis/profiles/create-link-session)で作成したリンク用 URL の状態を確認します —
ユーザーがそれを開いたか、まだ有効か、何回使用されたかがわかります。

ユーザーに尋ねることなくアカウント連携を開始したかどうかを知りたい場合や、代わりのリンクを作成する前に
リンクが無効になっていることを確認したい場合に便利です。

<Note>
  存在しない `sessionId` や、別のアカウントに属する `sessionId` は、同じ `not found` レスポンスを
  返します。これは意図的なもので、このエンドポイントを識別子が実在するかどうかの探索に利用できない
  ようにするためです。
</Note>

## ヘッダーパラメータ

<HeaderAPI profileKeyRequired={true} />

## パスパラメータ

<ParamField path="sessionId" type="string" required>
  リンクの作成時に返された `sessionId`。
</ParamField>

## リンクの状態

`state` フィールドは以下のいずれかです:

* `pending`: 作成済みで、一度も開かれていません。
* `active`: 少なくとも 1 回開かれ、まだ有効期間内です。
* `expired`: `expiresAt` を過ぎています。
* `revoked`: [Link Session の失効](/docs/apis/profiles/revoke-link-session)で無効化されました。

失効済みのリンクは、有効期間が過ぎた後も `revoked` を報告します。そのほうが有用な回答だからです。

## 接続されたアカウント

ユーザーがアカウントを接続すると、リンクはそれを記録します。何かが接続されると 3 つのフィールドが
現れ、それまでは存在しません:

* `completedAt`: 最初のアカウントが接続された時刻。
* `lastCompletedAt`: 最も新しいアカウントが接続された時刻。
* `completedNetworks`: このリンクで接続されたすべてのネットワーク。

これらは `state` とは別物で、どちらも現実の問いに答えます: リンクは `active` のままでまだ何も接続
していないこともあれば、期限が切れる前に 3 つのアカウントを接続して `expired` になっていることも
あります。`completedNetworks` のポーリングは、サーバーレンダリングされるアプリやモバイルアプリが
接続の完了を知る方法であり、帯域外で完了する Telegram にとっては唯一のシグナルです。

<Warning>
  **`completedNetworks` はこのリンクセッションの履歴であり、プロファイルの現在の状態ではありません。**
  追記専用です: ネットワークはこのセッションを通じて接続されたときに追加され、削除されることは
  ないため、アカウントがリンク解除された後も、別のセッションで再リンクされた後も、ネットワーク側で
  切断された後も、リストに残り続けます。**現時点で** User Profile にリンクされているネットワークを
  確認するには、`include=state` を付けて
  [Get User Profiles](/docs/apis/profiles/get-profiles) を呼び出してください。
</Warning>

<RequestExample>
  ```bash cURL theme={"system"}
  curl \
  -H "Authorization: Bearer API_KEY" \
  -H 'Profile-Key: PROFILE_KEY' \
  -X GET https://api.ayrshare.com/api/profiles/link-sessions/SESSION_ID
  ```

  ```javascript JavaScript theme={"system"}
  const API_KEY = "API_KEY";
  const PROFILE_KEY = "PROFILE_KEY";
  const SESSION_ID = "SESSION_ID";

  fetch(`https://api.ayrshare.com/api/profiles/link-sessions/${SESSION_ID}`, {
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "Profile-Key": PROFILE_KEY,
    },
  })
    .then((res) => res.json())
    .then((json) => console.log(json))
    .catch(console.error);
  ```

  ```python Python theme={"system"}
  import requests

  headers = {'Authorization': 'Bearer API_KEY',
          'Profile-Key': 'PROFILE_KEY'}

  response = requests.get(
      'https://api.ayrshare.com/api/profiles/link-sessions/SESSION_ID',
      headers=headers)
  print(response.json())
  ```

  ```php PHP theme={"system"}
  <?php
  require 'vendor/autoload.php';    // Composer auto-loader using Guzzle. See .../guzzlephp.org/en/stable/overview.html

  $client = new GuzzleHttp\Client();
  $res = $client->request(
      'GET',
      'https://api.ayrshare.com/api/profiles/link-sessions/SESSION_ID',
      [
          'headers' => [
              'Authorization' => 'Bearer API_KEY',
              'Profile-Key'   => 'PROFILE_KEY'
          ]
      ]
  );

  echo json_encode(json_decode($res->getBody()), JSON_PRETTY_PRINT);
  ```

  ```csharp C# theme={"system"}
  using System;
  using System.Net.Http;
  using System.Threading.Tasks;

  namespace GetLinkSession_csharp
  {
    class GetLinkSession
    {
        static async Task Main(string[] args)
        {
            string API_KEY = "API_KEY";
            string PROFILE_KEY = "PROFILE_KEY";
            string url = "https://api.ayrshare.com/api/profiles/link-sessions/SESSION_ID";

            try
            {
                using (var client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + API_KEY);
                    client.DefaultRequestHeaders.Add("Profile-Key", PROFILE_KEY);

                    HttpResponseMessage response = await client.GetAsync(url);
                    response.EnsureSuccessStatusCode();

                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseBody);
                }
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"HTTP request error: {e.Message}");
            }
        }
    }
  }
  ```
</RequestExample>

<ResponseExample>
  ```json 200: Opened Once, Still Valid theme={"system"}
  {
      "status": "success",
      "sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8",
      "state": "active",  // pending | active | expired | revoked - see Link States above.
      "createdAt": "2026-09-01T08:03:26.838Z",  // When the link was created, as an ISO 8601 timestamp.
      "expiresAt": "2026-09-02T08:03:26.838Z",  // When the link stops working.
      "firstUsedAt": "2026-09-01T08:14:02.104Z",  // When the link was first opened. Absent if it never has been.
      "lastUsedAt": "2026-09-01T08:14:02.104Z",  // When the link was most recently opened. Absent if it never has been.
      "useCount": 1,  // How many times the link has been opened. A reload or an OAuth retry increments this.
      "completedAt": "2026-09-01T08:15:44.870Z",  // When the first account was connected. Absent until one is.
      "lastCompletedAt": "2026-09-01T08:16:20.412Z",  // When the most recent was connected. Absent until one is.
      "completedNetworks": ["reddit", "bluesky"]  // Every network connected on this link, append-only. Absent until one is.
  }
  ```

  ```json 200: Created, Never Opened theme={"system"}
  {
      "status": "success",
      "sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8",
      "state": "pending",  // Created but never opened, so firstUsedAt and lastUsedAt are absent.
      "createdAt": "2026-09-01T08:03:26.838Z",
      "expiresAt": "2026-09-02T08:03:26.838Z",
      "useCount": 0
  }
  ```

  ```json 404: Not Found theme={"system"}
  {
    "action": "link session",
    "status": "error",
    "code": 502,
    "message": "Social linking session not found. Please request a new linking URL."
  }
  ```
</ResponseExample>
