curl --request POST \
--url https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"action_id": "<string>",
"note": "<string>",
"undone_by_external_ref": "<string>"
}
'import requests
url = "https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo"
payload = {
"action_id": "<string>",
"note": "<string>",
"undone_by_external_ref": "<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({action_id: '<string>', note: '<string>', undone_by_external_ref: '<string>'})
};
fetch('https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo', 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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo",
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([
'action_id' => '<string>',
'note' => '<string>',
'undone_by_external_ref' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo"
payload := strings.NewReader("{\n \"action_id\": \"<string>\",\n \"note\": \"<string>\",\n \"undone_by_external_ref\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"action_id\": \"<string>\",\n \"note\": \"<string>\",\n \"undone_by_external_ref\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"action_id\": \"<string>\",\n \"note\": \"<string>\",\n \"undone_by_external_ref\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"card_refiled": true,
"next_action": {
"accompanying_email": {
"body_markdown": "<string>",
"error": "<string>",
"execution_ref": "<string>",
"sent_at": "2023-11-07T05:31:56Z",
"status": "<string>",
"subject": "<string>",
"to": "<string>"
},
"action_input": {},
"action_kind": "<string>",
"approval_request_id": "<string>",
"canonical_lead_id": "<string>",
"created_by": "<string>",
"dataset_id": "<string>",
"decided_at": "2023-11-07T05:31:56Z",
"decided_by": "<string>",
"decided_by_external_ref": "<string>",
"due_at": "2023-11-07T05:31:56Z",
"error": "<string>",
"evaluated_at": "2023-11-07T05:31:56Z",
"executed_at": "2023-11-07T05:31:56Z",
"execution_ref": "<string>",
"facts": {
"bedrooms": {
"source_column": "<string>",
"value": "<string>"
},
"broker": {
"source_column": "<string>",
"value": "<string>"
},
"budget": {
"source_column": "<string>",
"value": "<string>"
},
"financing": {
"source_column": "<string>",
"value": "<string>"
},
"language": {
"source_column": "<string>",
"value": "<string>"
},
"purpose": {
"source_column": "<string>",
"value": "<string>"
},
"timeline": {
"source_column": "<string>",
"value": "<string>"
}
},
"handoff_alert": {
"error": "<string>",
"execution_ref": "<string>",
"sent_at": "2023-11-07T05:31:56Z",
"status": "<string>"
},
"id": "<string>",
"lead_reference": "<string>",
"mode": "<string>",
"model": "<string>",
"playbook_revision": 123,
"policy_digest": "<string>",
"priority": "<string>",
"priority_reason": "<string>",
"rationale": "<string>",
"revisit_at": "2023-11-07T05:31:56Z",
"rule": "<string>",
"source": "<string>",
"stage": "<string>",
"status": "<string>",
"undone_by_external_ref": "<string>"
},
"undone_at": "2023-11-07T05:31:56Z",
"undone_by": "<string>"
}{
"code": "not_found",
"details": {},
"message": "<string>"
}UndoLeadNextActionAPI takes back an approval that has not been carried out
and puts the decision back in front of a person.
Approving no longer sends anything: a decision waits in `approved` for the delivery step, and this is the window in which somebody can change their mind. Undo and delivery both claim that row atomically, so whichever runs first wins — an action that has already gone out answers FailedPrecondition rather than pretending to be recalled.
There is deliberately no MCP tool for this, for the same reason as the hold and the close: taking back a person’s approval is the sales desk’s call about a lead it is dealing with, not a model’s. A scoped API key is refused.
curl --request POST \
--url https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"action_id": "<string>",
"note": "<string>",
"undone_by_external_ref": "<string>"
}
'import requests
url = "https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo"
payload = {
"action_id": "<string>",
"note": "<string>",
"undone_by_external_ref": "<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({action_id: '<string>', note: '<string>', undone_by_external_ref: '<string>'})
};
fetch('https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo', 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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo",
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([
'action_id' => '<string>',
'note' => '<string>',
'undone_by_external_ref' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo"
payload := strings.NewReader("{\n \"action_id\": \"<string>\",\n \"note\": \"<string>\",\n \"undone_by_external_ref\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"action_id\": \"<string>\",\n \"note\": \"<string>\",\n \"undone_by_external_ref\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/next-actions/undo")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"action_id\": \"<string>\",\n \"note\": \"<string>\",\n \"undone_by_external_ref\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"card_refiled": true,
"next_action": {
"accompanying_email": {
"body_markdown": "<string>",
"error": "<string>",
"execution_ref": "<string>",
"sent_at": "2023-11-07T05:31:56Z",
"status": "<string>",
"subject": "<string>",
"to": "<string>"
},
"action_input": {},
"action_kind": "<string>",
"approval_request_id": "<string>",
"canonical_lead_id": "<string>",
"created_by": "<string>",
"dataset_id": "<string>",
"decided_at": "2023-11-07T05:31:56Z",
"decided_by": "<string>",
"decided_by_external_ref": "<string>",
"due_at": "2023-11-07T05:31:56Z",
"error": "<string>",
"evaluated_at": "2023-11-07T05:31:56Z",
"executed_at": "2023-11-07T05:31:56Z",
"execution_ref": "<string>",
"facts": {
"bedrooms": {
"source_column": "<string>",
"value": "<string>"
},
"broker": {
"source_column": "<string>",
"value": "<string>"
},
"budget": {
"source_column": "<string>",
"value": "<string>"
},
"financing": {
"source_column": "<string>",
"value": "<string>"
},
"language": {
"source_column": "<string>",
"value": "<string>"
},
"purpose": {
"source_column": "<string>",
"value": "<string>"
},
"timeline": {
"source_column": "<string>",
"value": "<string>"
}
},
"handoff_alert": {
"error": "<string>",
"execution_ref": "<string>",
"sent_at": "2023-11-07T05:31:56Z",
"status": "<string>"
},
"id": "<string>",
"lead_reference": "<string>",
"mode": "<string>",
"model": "<string>",
"playbook_revision": 123,
"policy_digest": "<string>",
"priority": "<string>",
"priority_reason": "<string>",
"rationale": "<string>",
"revisit_at": "2023-11-07T05:31:56Z",
"rule": "<string>",
"source": "<string>",
"stage": "<string>",
"status": "<string>",
"undone_by_external_ref": "<string>"
},
"undone_at": "2023-11-07T05:31:56Z",
"undone_by": "<string>"
}{
"code": "not_found",
"details": {},
"message": "<string>"
}Authorizations
An Erdo API key (erdo_api_...) or scoped token (erdo_token_...).
Response
Success response
now. False means the approval is undone — the action will not be carried out — but the new card has still to be filed, which the next sweep does.
Show child attributes
Show child attributes

