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

# Poll Agent Onboarding

> Poll for the result of a device-authorization flow started with /v1/agent/onboarding/start. No API key required.

### Overview

No authentication is required for this endpoint. Call it with the `device_code` from `/v1/agent/onboarding/start`, waiting at least the returned `interval` seconds between calls. See the [Agent onboarding API](https://docs.bland.ai/platform/connect-your-agent.md) for the full flow.

> [!NOTE]
>
> This endpoint has two independent `429` responses: `SLOW_DOWN` when you poll faster than the per-device `interval`, and `TOO_MANY_REQUESTS` from the per-IP rate limit (600 requests per minute per IP, since a hosting platform's shared egress address can carry many bots), which carries a `Retry-After` header instead of `interval`.

### Body Parameters

**device\_code** `string` *required*

The `device_code` returned by `/v1/agent/onboarding/start`.

### Response

**data** `object`

Current state of the flow.

**data.status** `string`

One of `pending`, `approved`, `expired`.

**data.interval** `number`

Present when `status` is `pending`. Minimum seconds to wait before polling again.

**data.expires\_in** `number`

Present when `status` is `pending`. Seconds remaining before the codes expire.

**data.api\_key** `string`

Present only when `status` is `approved`. A dedicated API key for the org, returned exactly once.

**data.org\_id** `string`

Present when `status` is `approved`. The org the key belongs to.

**data.phone\_number** `string | null`

Present when `status` is `approved`. The number provisioned for this org, or `null` when the owner connected the bot without the Agent Phone Plan. Without the plan, calls go out from Bland's shared pool of numbers and texting is not included.

**data.plan** `object`

Present when `status` is `approved`. The org's Agent Phone Plan subscription. When the owner connected the bot on free credits instead, `plan.status` is `none` and every other `plan` field is `null`. The same object is returned by `GET /billing/agent_phone` (as `data`) and by `GET /v1/me` (as `plan`).

**data.plan.name** `string | null`

Internal plan identifier, `agent_phone_basic`. `null` when there is no plan.

**data.plan.display\_name** `string | null`

Human-readable plan name, `Agent Phone Plan`. `null` when there is no plan.

**data.plan.status** `string`

Subscription status: `active`, or `none` when the org has no Agent Phone Plan.

**data.plan.phone\_number** `string | null`

The number provisioned for this org's Agent Phone Plan. `null` when there is no plan.

**data.plan.concurrency** `number | null`

Maximum concurrent calls, `1`. `null` when there is no plan.

**data.plan.max\_call\_duration\_minutes** `number | null`

Maximum call length in minutes, `60`. `null` when there is no plan.

**data.plan.allowed\_countries** `array | null`

Country codes calls, transfers, and SMS are allowed to, `["US", "CA"]`. `null` when there is no plan.

**data.plan.current\_period\_end** `string | null`

ISO 8601 timestamp for the end of the current billing period. `null` when there is no plan.

**data.client\_name** `string`

Present when `status` is `approved`, if a `client_name` was given to `/start`.

**errors** `null | array`

`null` unless polling too fast.

```json Pending theme={null}
{
  "data": {
    "status": "pending",
    "interval": 5,
    "expires_in": 823
  },
  "errors": null
}
```

```json Approved with the plan theme={null}
{
  "data": {
    "status": "approved",
    "api_key": "org_...",
    "org_id": "...",
    "phone_number": "+14155550123",
    "plan": {
      "name": "agent_phone_basic",
      "display_name": "Agent Phone Plan",
      "status": "active",
      "phone_number": "+14155550123",
      "concurrency": 1,
      "max_call_duration_minutes": 60,
      "allowed_countries": ["US", "CA"],
      "current_period_end": "2026-10-07T00:00:00.000Z"
    },
    "client_name": "my-bot"
  },
  "errors": null
}
```

```json Approved with free credits theme={null}
{
  "data": {
    "status": "approved",
    "api_key": "org_...",
    "org_id": "...",
    "phone_number": null,
    "plan": {
      "name": null,
      "display_name": null,
      "status": "none",
      "phone_number": null,
      "concurrency": null,
      "max_call_duration_minutes": null,
      "allowed_countries": null,
      "current_period_end": null
    },
    "client_name": "my-bot"
  },
  "errors": null
}
```

```json Expired theme={null}
{
  "data": {
    "status": "expired"
  },
  "errors": null
}
```

```json Too fast (429) theme={null}
{
  "data": null,
  "errors": [
    {
      "error": "SLOW_DOWN",
      "message": "Poll more slowly.",
      "interval": 10
    }
  ]
}
```

```json Too many requests (429) theme={null}
{
  "data": null,
  "errors": [
    {
      "error": "TOO_MANY_REQUESTS",
      "message": "Too many requests. Try again later."
    }
  ]
}
```

> [!NOTE]
>
> An `expired` status covers both an expired code and a `device_code` that was never valid. The two aren't distinguished, so don't rely on this response to debug a mistyped code, start over with a new `/start` call instead.

***

Docs for agents: [llms.txt](https://docs.bland.ai/llms.txt)


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