# GET /v1/social/oauth-status/:state (/docs/api/reference/social-accounts/oauth-status)



<Endpoint method="GET" path="/v1/social/oauth-status/:state" auth="Bearer" scope="social:read" phase="1" />

Poll this endpoint with the `state` you got back from [`POST /v1/projects/:id/social/oauth-url`](/docs/api/reference/social-accounts/oauth-url) to learn whether the end-customer completed consent and, if so, which `socialAccountId` was created.

The endpoint is not project-scoped — the `state` token uniquely identifies the attempt, and Layers scopes results by the API key that created it (a state created under key A is invisible to key B).

Poll at 2-second intervals with jitter for up to 10 minutes. After that, the state expires and you create a new URL. Don't poll faster than once per second per `state`.

<Parameters
  title="Path"
  rows="[
  { name: 'state', type: 'string', required: true, description: 'Opaque state token from oauth-url. Case-sensitive.' },
]"
/>

## Example request [#example-request]

<Tabs items="['curl', 'TypeScript', 'Python']">
  <Tab value="curl">
    ```bash
    curl "https://api.layers.com/v1/social/oauth-status/st_01HXZ8K2M4P5QRS6TUV7WXYZ9A" \
      -H "Authorization: Bearer lp_live_01HX9Y6K7EJ4T2_4QZpN..."
    ```
  </Tab>

  <Tab value="TypeScript">
    ```ts
    async function waitForOAuth(state: string) {
      const deadline = Date.now() + 10 * 60 * 1000;
      while (Date.now() < deadline) {
        const status = await layers.social.getOAuthStatus({ state });
        if (status.status === "completed") return status.socialAccountId;
        if (status.status === "failed") throw new Error(status.error?.message ?? "OAuth failed");
        await new Promise((r) => setTimeout(r, 2000 + Math.random() * 500));
      }
      throw new Error("OAuth timed out");
    }
    ```
  </Tab>

  <Tab value="Python">
    ```python
    import time, random

    def wait_for_oauth(state: str) -> str:
        deadline = time.time() + 600
        while time.time() < deadline:
            status = layers.social.get_oauth_status(state=state)
            if status["status"] == "completed":
                return status["socialAccountId"]
            if status["status"] == "failed":
                raise RuntimeError(status.get("error", {}).get("message", "OAuth failed"))
            time.sleep(2 + random.random() * 0.5)
        raise TimeoutError("OAuth timed out")
    ```
  </Tab>
</Tabs>

## Response [#response]

<Response status="200" description="Pending — keep polling">
  ```json
  {
    "state": "st_01HXZ8K2M4P5QRS6TUV7WXYZ9A",
    "status": "pending",
    "expiresAt": "2026-04-18T19:12:11Z"
  }
  ```
</Response>

<Response status="200" description="Completed — account connected">
  ```json
  {
    "state": "st_01HXZ8K2M4P5QRS6TUV7WXYZ9A",
    "status": "completed",
    "socialAccountId": "sa_01HXZ9P2M4N5KLM6TUV7WXYZ9A",
    "platform": "tiktok",
    "handle": "acmecoffee",
    "connectedAt": "2026-04-18T19:06:42Z"
  }
  ```
</Response>

<Response status="200" description="Failed — user denied or platform rejected">
  ```json
  {
    "state": "st_01HXZ8K2M4P5QRS6TUV7WXYZ9A",
    "status": "failed",
    "error": {
      "code": "USER_DENIED",
      "message": "The user did not grant consent on the platform."
    }
  }
  ```
</Response>

## Errors [#errors]

| Status | Code              | When                                                               |
| ------ | ----------------- | ------------------------------------------------------------------ |
| 401    | `UNAUTHENTICATED` | Missing or invalid key.                                            |
| 403    | `FORBIDDEN_SCOPE` | Key lacks `social:read`.                                           |
| 404    | `NOT_FOUND`       | `state` unknown, expired, or created under a different project.    |
| 429    | `RATE_LIMITED`    | Polling budget exhausted — back off with the `Retry-After` header. |

## See also [#see-also]

* [`POST /v1/projects/:id/social/oauth-url`](/docs/api/reference/social-accounts/oauth-url) — create the URL
* [`GET /v1/projects/:id/social-accounts`](/docs/api/reference/social-accounts/list-social-accounts) — enumerate connected accounts
