Agent Onboarding
Approve Agent Onboarding
Claim a device-authorization code after the owner signs up in the browser. Called by the Bland dashboard, not by the bot.
POST
/
v1
/
agent
/
onboarding
/
approve
Approve Agent Onboarding
curl --request POST \
--url https://api.bland.ai/v1/agent/onboarding/approve \
--header 'Content-Type: application/json' \
--data '
{
"user_code": "<string>",
"skip_plan": true
}
'import requests
url = "https://api.bland.ai/v1/agent/onboarding/approve"
payload = {
"user_code": "<string>",
"skip_plan": True
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({user_code: '<string>', skip_plan: true})
};
fetch('https://api.bland.ai/v1/agent/onboarding/approve', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bland.ai/v1/agent/onboarding/approve",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'user_code' => '<string>',
'skip_plan' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bland.ai/v1/agent/onboarding/approve"
payload := strings.NewReader("{\n \"user_code\": \"<string>\",\n \"skip_plan\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.bland.ai/v1/agent/onboarding/approve")
.header("Content-Type", "application/json")
.body("{\n \"user_code\": \"<string>\",\n \"skip_plan\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bland.ai/v1/agent/onboarding/approve")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"user_code\": \"<string>\",\n \"skip_plan\": true\n}"
response = http.request(request)
puts response.read_body{
"data": {
"status": "approved",
"org_id": "...",
"phone_number": "+15551234567",
"client_name": "my-bot",
"key_prefix": "org_3f9a1c7e2b"
},
"errors": null
}
{
"data": {
"status": "approved",
"org_id": "...",
"phone_number": null,
"client_name": "my-bot",
"key_prefix": "org_3f9a1c7e2b"
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "INVALID_USER_CODE",
"message": "Enter the code your agent gave you."
}
]
}
{
"data": null,
"errors": [
{
"error": "PLAN_REQUIRED",
"message": "Start the Agent Phone Plan to connect your agent."
}
]
}
{
"data": null,
"errors": [
{
"error": "PLAN_NUMBER_PENDING",
"message": "Your number is still being set up. Try again in a moment."
}
]
}
{
"data": null,
"errors": [
{
"error": "CODE_NOT_FOUND",
"message": "That code is not valid. Ask your agent for a new one."
}
]
}
{
"data": null,
"errors": [
{
"error": "CODE_ALREADY_USED",
"message": "That code has already been used. Ask your agent for a new one."
}
]
}
{
"data": null,
"errors": [
{
"error": "ORG_CONTEXT_REQUIRED",
"message": "Switch to an organization to connect an agent."
}
]
}
{
"data": null,
"errors": [
{
"error": "INVALID_ORIGIN",
"message": "Approve this code from the Bland dashboard. This request did not come from it."
}
]
}
{
"data": null,
"errors": [
{
"error": "TOO_MANY_REQUESTS",
"message": "Too many attempts. Wait a few minutes and try again."
}
]
}
Overview
This endpoint is called from the browser by the dashboard during the agent onboarding flow, after the owner signs up (or logs in) and either starts the Agent Phone Plan or chooses to connect the bot on the org’s free credits. It isn’t called directly by the bot, the bot only ever sees its effect through/v1/agent/onboarding/poll.
Requires an authenticated dashboard session for an org (not a personal account, and not an API key). The response never includes the
api_key, only the bot’s later poll call receives it.Body Parameters
string
required
The short code shown to the owner by
/v1/agent/onboarding/start.boolean
Pass
true to connect the bot without an Agent Phone Plan, on the org’s free credits. Strictly a boolean; "true" as a string is rejected. Without it, an org that has no active plan gets 402 PLAN_REQUIRED. An org that already has an active plan ignores skip_plan entirely: the plan payload is returned as usual, including the PLAN_NUMBER_PENDING wait while its number is provisioned.Response
object
Confirmation that the code was claimed for this org.
string
approved.string
The org the code was claimed for.
string | null
The number provisioned for this org’s Agent Phone Plan, or
null when the code was approved with skip_plan: true and the org has no plan.string
The
client_name the bot passed to /start, if any.string
The first 14 characters of the API key that will be issued to the bot, the same handle Settings > API Keys shows. Display only, never the key itself.
null | array
null on success.{
"data": {
"status": "approved",
"org_id": "...",
"phone_number": "+15551234567",
"client_name": "my-bot",
"key_prefix": "org_3f9a1c7e2b"
},
"errors": null
}
{
"data": {
"status": "approved",
"org_id": "...",
"phone_number": null,
"client_name": "my-bot",
"key_prefix": "org_3f9a1c7e2b"
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "INVALID_USER_CODE",
"message": "Enter the code your agent gave you."
}
]
}
{
"data": null,
"errors": [
{
"error": "PLAN_REQUIRED",
"message": "Start the Agent Phone Plan to connect your agent."
}
]
}
{
"data": null,
"errors": [
{
"error": "PLAN_NUMBER_PENDING",
"message": "Your number is still being set up. Try again in a moment."
}
]
}
{
"data": null,
"errors": [
{
"error": "CODE_NOT_FOUND",
"message": "That code is not valid. Ask your agent for a new one."
}
]
}
{
"data": null,
"errors": [
{
"error": "CODE_ALREADY_USED",
"message": "That code has already been used. Ask your agent for a new one."
}
]
}
{
"data": null,
"errors": [
{
"error": "ORG_CONTEXT_REQUIRED",
"message": "Switch to an organization to connect an agent."
}
]
}
{
"data": null,
"errors": [
{
"error": "INVALID_ORIGIN",
"message": "Approve this code from the Bland dashboard. This request did not come from it."
}
]
}
{
"data": null,
"errors": [
{
"error": "TOO_MANY_REQUESTS",
"message": "Too many attempts. Wait a few minutes and try again."
}
]
}
Docs for agents: llms.txt
Was this page helpful?
⌘I
Approve Agent Onboarding
curl --request POST \
--url https://api.bland.ai/v1/agent/onboarding/approve \
--header 'Content-Type: application/json' \
--data '
{
"user_code": "<string>",
"skip_plan": true
}
'import requests
url = "https://api.bland.ai/v1/agent/onboarding/approve"
payload = {
"user_code": "<string>",
"skip_plan": True
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({user_code: '<string>', skip_plan: true})
};
fetch('https://api.bland.ai/v1/agent/onboarding/approve', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bland.ai/v1/agent/onboarding/approve",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'user_code' => '<string>',
'skip_plan' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bland.ai/v1/agent/onboarding/approve"
payload := strings.NewReader("{\n \"user_code\": \"<string>\",\n \"skip_plan\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.bland.ai/v1/agent/onboarding/approve")
.header("Content-Type", "application/json")
.body("{\n \"user_code\": \"<string>\",\n \"skip_plan\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bland.ai/v1/agent/onboarding/approve")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"user_code\": \"<string>\",\n \"skip_plan\": true\n}"
response = http.request(request)
puts response.read_body{
"data": {
"status": "approved",
"org_id": "...",
"phone_number": "+15551234567",
"client_name": "my-bot",
"key_prefix": "org_3f9a1c7e2b"
},
"errors": null
}
{
"data": {
"status": "approved",
"org_id": "...",
"phone_number": null,
"client_name": "my-bot",
"key_prefix": "org_3f9a1c7e2b"
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "INVALID_USER_CODE",
"message": "Enter the code your agent gave you."
}
]
}
{
"data": null,
"errors": [
{
"error": "PLAN_REQUIRED",
"message": "Start the Agent Phone Plan to connect your agent."
}
]
}
{
"data": null,
"errors": [
{
"error": "PLAN_NUMBER_PENDING",
"message": "Your number is still being set up. Try again in a moment."
}
]
}
{
"data": null,
"errors": [
{
"error": "CODE_NOT_FOUND",
"message": "That code is not valid. Ask your agent for a new one."
}
]
}
{
"data": null,
"errors": [
{
"error": "CODE_ALREADY_USED",
"message": "That code has already been used. Ask your agent for a new one."
}
]
}
{
"data": null,
"errors": [
{
"error": "ORG_CONTEXT_REQUIRED",
"message": "Switch to an organization to connect an agent."
}
]
}
{
"data": null,
"errors": [
{
"error": "INVALID_ORIGIN",
"message": "Approve this code from the Bland dashboard. This request did not come from it."
}
]
}
{
"data": null,
"errors": [
{
"error": "TOO_MANY_REQUESTS",
"message": "Too many attempts. Wait a few minutes and try again."
}
]
}