curl --request POST \
--url https://api.callva.io/api/v1/external/agents/{id}/clone \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>"
}
'import requests
url = "https://api.callva.io/api/v1/external/agents/{id}/clone"
payload = { "name": "<string>" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '<string>'})
};
fetch('https://api.callva.io/api/v1/external/agents/{id}/clone', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"success": true,
"message": "Agent cloned successfully",
"data": {
"id": "<string>",
"name": "<string>",
"preset": "<string>",
"source_agent_id": "<string>",
"presets_copied": [
"<unknown>"
],
"phone_numbers_copied": true
}
}{
"success": true,
"message": "Project context required"
}{
"error": "Invalid or expired token",
"message": "The provided token is invalid or has expired"
}{
"success": true,
"message": "Insufficient permission.",
"code": "insufficient_permission"
}{
"success": true,
"message": "Agent not found"
}{
"success": true,
"message": "Validation failed",
"errors": {}
}{
"success": true,
"message": "<string>"
}Clone an agent
Requires permission: agents.create.
What a token may call depends on its role: see Authentication and permissions.
Body: { "name": "..." } - optional; a name is derived from the source’s
when none is given.
What the copy carries: everything that survives a stack swap - name,
prompt, knowledge, greeting, who speaks first, farewell, duration and
silence limits, prompt attempts and phrases, webhook configuration,
overrides - plus the agent’s active preset, every agent_preset row
it holds, and every agent_tool row. Every row, because the point of the copy is
to vary one stack while holding the others equal: a clone that dropped
the stacks the operator was not currently looking at would make the
comparison it exists to serve impossible.
What it deliberately does not carry:
- Phone numbers.
provisioned_phone_numbers.assigned_agent_idis a single foreign key, so a number belongs to one agent and two agents cannot share it. The clone gets none, and the response says so rather than leaving the operator to discover it through an inbound call that never arrives. - Default and system status. The project already has a default agent, and a copy an operator asked for is theirs rather than the platform’s.
- Calls, transcripts and webhook logs. They are the history of the agent that made them.
curl --request POST \
--url https://api.callva.io/api/v1/external/agents/{id}/clone \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>"
}
'import requests
url = "https://api.callva.io/api/v1/external/agents/{id}/clone"
payload = { "name": "<string>" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '<string>'})
};
fetch('https://api.callva.io/api/v1/external/agents/{id}/clone', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"success": true,
"message": "Agent cloned successfully",
"data": {
"id": "<string>",
"name": "<string>",
"preset": "<string>",
"source_agent_id": "<string>",
"presets_copied": [
"<unknown>"
],
"phone_numbers_copied": true
}
}{
"success": true,
"message": "Project context required"
}{
"error": "Invalid or expired token",
"message": "The provided token is invalid or has expired"
}{
"success": true,
"message": "Insufficient permission.",
"code": "insufficient_permission"
}{
"success": true,
"message": "Agent not found"
}{
"success": true,
"message": "Validation failed",
"errors": {}
}{
"success": true,
"message": "<string>"
}Authorizations
A CallVA API token, sent as Authorization: Bearer <token>.
Creating one. In the CallVA dashboard, open the organization's Settings, then API Keys, and choose Create API Key: give the key a name, choose its role, and choose its project scope - All projects for an organization-wide token, or one project for a project token. The key is shown once, when it is created, and cannot be read again; store it then. Creating keys needs the api_tokens.create permission, which owners and admins hold, and a key cannot create another key.
Organization-wide or project token. A project token works in the one project it was created for; any project named in the request is ignored. An organization-wide token reaches the projects of its organization, and each request names its project with the X-Project-ID header or project_id (query string for reads and deletes, body for writes).
What it can call. The token's role decides which endpoints it may call; each endpoint names the permission it requires, and a token whose role lacks it is answered 403.
Headers
The project this request acts in. Required with an organization-wide token (or send project_id instead); ignored with a project token, which always acts in its own project.
Path Parameters
Body
255