# Check how a connection sign-in ended

**GET** `/api/embed/v1/accounts/{accountId}/connections/oauth2/attempts/{attemptId}`

Reads how a connection sign-in your server started has ended: `pending`, then `connected` or `failed`.

Needs a partner key: `Authorization: Bearer gre_…`, from [Platform › Partner keys](https://docs.gorunner.io/embed/platform-screens#partner-keys). It sees only sign-ins that this key started for this account.

Embed · Self-hosted with an Embed license

## Parameters

### Path

- `accountId` · Required · string: Your ID for the customer’s account: 1 to 255 bytes of UTF-8, case-sensitive. URL-encode it: an ID may contain `/`.
- `attemptId` · Required · string: The `attemptId` that [Start a connection sign-in from your own button](https://docs.gorunner.io/embed/api/connections/start-connection-sign-in) answered.

No query, headers or body beyond the key.

Request

**curl**

```bash
GORUNNER="https://automations.example.com"
GORUNNER_EMBED_KEY="YOUR_PARTNER_KEY"  # gre_…, from Platform › Partner keys
ACCOUNT_URL="$GORUNNER/api/embed/v1/accounts/acct-bakery"
ATTEMPT="Zq3XbN0iJm7dQe8TfR2wLg"  # from the start

curl "$ACCOUNT_URL/connections/oauth2/attempts/$ATTEMPT" \
  -H "Authorization: Bearer $GORUNNER_EMBED_KEY"
```

**JavaScript**

```js
const GORUNNER = "https://automations.example.com";
const KEY = process.env.GORUNNER_EMBED_KEY; // gre_…
const account = encodeURIComponent("acct-bakery");
const attemptId = "Zq3XbN0iJm7dQe8TfR2wLg"; // from the start

const res = await fetch(
  `${GORUNNER}/api/embed/v1/accounts/${account}` +
    `/connections/oauth2/attempts/${attemptId}`,
  { headers: { Authorization: `Bearer ${KEY}` } },
);
const { data } = await res.json(); // data.status
```

**Python**

```python
import os, requests
from urllib.parse import quote

GORUNNER = "https://automations.example.com"
KEY = os.environ["GORUNNER_EMBED_KEY"]  # gre_…
account = quote("acct-bakery", safe="")
attempt_id = "Zq3XbN0iJm7dQe8TfR2wLg"  # from the start

res = requests.get(
    f"{GORUNNER}/api/embed/v1/accounts/{account}"
    f"/connections/oauth2/attempts/{attempt_id}",
    headers={"Authorization": f"Bearer {KEY}"},
)
data = res.json()["data"]  # data["status"]
```

Response · 200 OK

```json
{
  "data": {
    "attemptId": "Zq3XbN0iJm7dQe8TfR2wLg",
    "status": "connected",
    "connectionId": "0f8b2c7e-4a51-4d3e-9b2a-6c1d2e3f4a5b",
    "account": "ada@bakery.example",
    "expiresAt": "2026-10-21T12:10:00Z"
  }
}
```

## What the status means

- `pending`: The provider hasn’t sent the browser back yet. Ask again in a few seconds.
- `connected`: The connection holds its tokens. `connectionId` names it. `account` says who signed in, when the test after the sign-in named them.
- `failed`: `reason` says why, and `error` says it as a sentence for a person.

### Reasons

- `denied`: The person said no on the provider’s page.
- `service_error`: The provider answered with an error.
- `failed`: Something went wrong on GoRunner’s side.
- `cancelled`: The sign-in was stopped.
- `expired`: The sign-in link ran out first.

A sign-in can be read for an hour after its link runs out.

Response · 200 OK, failed

```json
{
  "data": {
    "attemptId": "Zq3XbN0iJm7dQe8TfR2wLg",
    "status": "failed",
    "reason": "denied",
    "error": "…a sentence for a person",
    "expiresAt": "2026-10-21T12:10:00Z"
  }
}
```

## Responses

- 200 OK

  Where the sign-in stands.

- 404 `NOT_FOUND`

  No such account, or no sign-in with that ID started by this key for it.

- 500 `INTERNAL_ERROR`

  The sign-in couldn’t be read. Try again.

- 503 `UNAVAILABLE`

  Sign-ins can’t be read on this server now. Try again.

Any call can also answer: [`401 UNAUTHORIZED`](https://docs.gorunner.io/errors#UNAUTHORIZED) · [`403 EMBED_NOT_LICENSED`](https://docs.gorunner.io/errors#EMBED_NOT_LICENSED) · [`403 IP_NOT_ALLOWED`](https://docs.gorunner.io/errors#IP_NOT_ALLOWED) · [`429 RATE_LIMITED`](https://docs.gorunner.io/errors#RATE_LIMITED). See [Errors](https://docs.gorunner.io/embed/api#errors).

Response · 404 Not Found

```json
{
  "error": {
    "code": "NOT_FOUND",
    "message": "…"
  }
}
```

**Every field**

It takes no body.

### Response · 200 OK

- `data` · object
  - `attemptId` · string
  - `status` · string: `pending` — the provider has not sent the browser back yet; `connected` — the connection holds its tokens; `failed` — see `reason`. One of `pending`, `connected`, `failed`.
  - `connectionId` · UUID: Only when `connected`: the connection made (or signed in again).
  - `reason` · string: Only when `failed`: `denied` — the person said no on the provider’s page; `service_error` — the provider answered with an error; `failed` — anything on this side; `cancelled` — the sign-in was stopped (`POST /api/connections/oauth2/attempts/{attemptId}/cancel`, by the token that started it; no partner endpoint stops one); `expired` — the link ran out first. One of `denied`, `service_error`, `failed`, `cancelled`, `expired`.
  - `error` · string: Only when `failed`: why, as a sentence for a person.
  - `account` · string: Only when `connected`: who signed in, when the test after the sign-in named them.
  - `expiresAt` · time

Related: [Start a connection sign-in from your own button](https://docs.gorunner.io/embed/api/connections/start-connection-sign-in) · [Your customers’ connections](https://docs.gorunner.io/embed/customer-connections) · [Partner API](https://docs.gorunner.io/embed/api)

Source: https://docs.gorunner.io/embed/api/connections/get-connection-sign-in
