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

# Check a Connection

> Read the outcome of a connection that needed authorizing

Report what happened to an OAuth connection after [Connect an Integration](/api-reference/v1-integration/connect-integration) returned `pending_authorization`.

An OAuth flow finishes in a browser, not in your call: a person opens the `authorizationUrl`, authorizes with the provider, and is returned to Opus. Your request is long gone by then. This endpoint is how you learn whether it worked and which connection resulted.

Requires the **Integration: Read** permission in at least one workspace. The connection is matched against the workspaces you hold it in, so a token from a workspace you cannot read is reported as `expired`.

<Note>
  Only needed for OAuth. A non-OAuth connect returns its ids immediately and there is nothing to poll.
</Note>

## Headers

<ParamField header="x-service-key" type="string" required>
  Your API authentication key
</ParamField>

## Path Parameters

<ParamField path="connectionToken" type="string" required>
  The `connectionToken` returned by [Connect an Integration](/api-reference/v1-integration/connect-integration).
</ParamField>

## Statuses

<ResponseField name="pending" type="status">
  The authorization window is still open. Nobody has finished authorizing yet.
</ResponseField>

<ResponseField name="succeeded" type="status">
  Someone authorized and the connection exists. The ids are on the response.
</ResponseField>

<ResponseField name="failed" type="status">
  Authorization was attempted and did not complete — a denied consent screen, or a token exchange the provider rejected.
</ResponseField>

<ResponseField name="expired" type="status">
  The window closed without a callback, the token is not one of yours, or there is no such token at all. Start again with a fresh connect.
</ResponseField>

<Warning>
  The authorization window is **10 minutes** from the connect call. A person who takes longer — or who has to create an account with the provider first — will find the link dead, and this endpoint reports `expired`. Connect again to get a fresh `authorizationUrl`.
</Warning>

## Response

<ResponseField name="status" type="string" required>
  One of `pending`, `succeeded`, `failed` or `expired`. Every field below is always present on the response; they are `null` until a connection exists.
</ResponseField>

<ResponseField name="activeIntegrationId" type="string">
  The connection — this is what a workflow refers to. Present once the status is `succeeded`.
</ResponseField>

<ResponseField name="activeIntegrationVersionId" type="string">
  The connection's current version.
</ResponseField>

<ResponseField name="activeCredentialId" type="string">
  The stored credential.
</ResponseField>

<ResponseField name="workspaceId" type="string">
  The workspace the connection lives in.
</ResponseField>

<ResponseField name="testPassed" type="boolean">
  Whether the smoke test succeeded. `null` when no `testActionVersionId` was sent to connect, because nothing was tested.
</ResponseField>

<ResponseField name="testError" type="string">
  Why it failed, when it did.
</ResponseField>

## Errors

<ResponseField name="401" type="Unauthorized">
  Missing, invalid, or expired API key.
</ResponseField>

<ResponseField name="403" type="Forbidden">
  The key owner lacks the **Integration: Read** permission.
</ResponseField>

<Note>
  There is deliberately no `404`. A token that belongs to someone else, and a token that was never issued, both come back as `expired` — the same answer as one of yours that timed out. If an unknown token answered differently, this endpoint could be used to discover whether someone else's connection exists.

  The practical consequence: `expired` does not confirm you sent a real token. Check for a typo before assuming the window closed.
</Note>

<RequestExample>
  ```bash cURL theme={null}
  curl --request GET \
    --url https://operator.opus.com/api/v1/integration/connect/{CONNECTION_TOKEN} \
    --header 'x-service-key: {YOUR_SERVICE_KEY}'
  ```

  ```python Python theme={null}
  import time

  import requests

  token = "{CONNECTION_TOKEN}"
  url = f"https://operator.opus.com/api/v1/integration/connect/{token}"
  headers = {"x-service-key": "{YOUR_SERVICE_KEY}"}

  # The window is 10 minutes; give up rather than poll forever.
  deadline = time.time() + 600
  while time.time() < deadline:
      status = requests.get(url, headers=headers).json()
      if status["status"] != "pending":
          break
      time.sleep(5)

  print(status)
  ```

  ```javascript JavaScript theme={null}
  const token = "{CONNECTION_TOKEN}";
  const url = `https://operator.opus.com/api/v1/integration/connect/${token}`;
  const headers = { "x-service-key": "{YOUR_SERVICE_KEY}" };

  // The window is 10 minutes; give up rather than poll forever.
  const deadline = Date.now() + 600_000;
  let status;

  while (Date.now() < deadline) {
    status = await (await fetch(url, { headers })).json();
    if (status.status !== "pending") break;
    await new Promise((resolve) => setTimeout(resolve, 5000));
  }

  console.log(status);
  ```
</RequestExample>

<ResponseExample>
  ```json 200 Succeeded theme={null}
  {
    "status": "succeeded",
    "activeIntegrationId": "{ACTIVE_INTEGRATION_ID}",
    "activeIntegrationVersionId": "{ACTIVE_INTEGRATION_VERSION_ID}",
    "activeCredentialId": "{ACTIVE_CREDENTIAL_ID}",
    "workspaceId": "{WORKSPACE_ID}",
    "testPassed": null,
    "testError": null
  }
  ```

  ```json 200 Pending theme={null}
  {
    "status": "pending",
    "activeIntegrationId": null,
    "activeIntegrationVersionId": null,
    "activeCredentialId": null,
    "workspaceId": "{WORKSPACE_ID}",
    "testPassed": null,
    "testError": null
  }
  ```
</ResponseExample>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.