curl --request PUT \
--url https://api.erdo.ai/v1/dataset-row-actions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"after": "<string>",
"backfill": "<string>",
"dataset": "<string>",
"destination": {
"columns": {},
"dataset": "<string>",
"key_column": "<string>"
},
"enabled": true,
"key_column": "<string>",
"key_fallback_columns": [
"<string>"
],
"name": "<string>",
"on_update": "<string>",
"skip_when": "<string>",
"steps": [
{
"app": "<string>",
"fallback": true,
"for_each": {},
"found_when": "<string>",
"input": {},
"key": "<string>",
"result_path": "<string>",
"script": "<string>"
}
],
"timestamp_column": "<string>",
"validate_only": true
}
'import requests
url = "https://api.erdo.ai/v1/dataset-row-actions"
payload = {
"after": "<string>",
"backfill": "<string>",
"dataset": "<string>",
"destination": {
"columns": {},
"dataset": "<string>",
"key_column": "<string>"
},
"enabled": True,
"key_column": "<string>",
"key_fallback_columns": ["<string>"],
"name": "<string>",
"on_update": "<string>",
"skip_when": "<string>",
"steps": [
{
"app": "<string>",
"fallback": True,
"for_each": {},
"found_when": "<string>",
"input": {},
"key": "<string>",
"result_path": "<string>",
"script": "<string>"
}
],
"timestamp_column": "<string>",
"validate_only": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
after: '<string>',
backfill: '<string>',
dataset: '<string>',
destination: {columns: {}, dataset: '<string>', key_column: '<string>'},
enabled: true,
key_column: '<string>',
key_fallback_columns: ['<string>'],
name: '<string>',
on_update: '<string>',
skip_when: '<string>',
steps: [
{
app: '<string>',
fallback: true,
for_each: {},
found_when: '<string>',
input: {},
key: '<string>',
result_path: '<string>',
script: '<string>'
}
],
timestamp_column: '<string>',
validate_only: true
})
};
fetch('https://api.erdo.ai/v1/dataset-row-actions', 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/dataset-row-actions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'after' => '<string>',
'backfill' => '<string>',
'dataset' => '<string>',
'destination' => [
'columns' => [
],
'dataset' => '<string>',
'key_column' => '<string>'
],
'enabled' => true,
'key_column' => '<string>',
'key_fallback_columns' => [
'<string>'
],
'name' => '<string>',
'on_update' => '<string>',
'skip_when' => '<string>',
'steps' => [
[
'app' => '<string>',
'fallback' => true,
'for_each' => [
],
'found_when' => '<string>',
'input' => [
],
'key' => '<string>',
'result_path' => '<string>',
'script' => '<string>'
]
],
'timestamp_column' => '<string>',
'validate_only' => true
]),
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/dataset-row-actions"
payload := strings.NewReader("{\n \"after\": \"<string>\",\n \"backfill\": \"<string>\",\n \"dataset\": \"<string>\",\n \"destination\": {\n \"columns\": {},\n \"dataset\": \"<string>\",\n \"key_column\": \"<string>\"\n },\n \"enabled\": true,\n \"key_column\": \"<string>\",\n \"key_fallback_columns\": [\n \"<string>\"\n ],\n \"name\": \"<string>\",\n \"on_update\": \"<string>\",\n \"skip_when\": \"<string>\",\n \"steps\": [\n {\n \"app\": \"<string>\",\n \"fallback\": true,\n \"for_each\": {},\n \"found_when\": \"<string>\",\n \"input\": {},\n \"key\": \"<string>\",\n \"result_path\": \"<string>\",\n \"script\": \"<string>\"\n }\n ],\n \"timestamp_column\": \"<string>\",\n \"validate_only\": true\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.erdo.ai/v1/dataset-row-actions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"after\": \"<string>\",\n \"backfill\": \"<string>\",\n \"dataset\": \"<string>\",\n \"destination\": {\n \"columns\": {},\n \"dataset\": \"<string>\",\n \"key_column\": \"<string>\"\n },\n \"enabled\": true,\n \"key_column\": \"<string>\",\n \"key_fallback_columns\": [\n \"<string>\"\n ],\n \"name\": \"<string>\",\n \"on_update\": \"<string>\",\n \"skip_when\": \"<string>\",\n \"steps\": [\n {\n \"app\": \"<string>\",\n \"fallback\": true,\n \"for_each\": {},\n \"found_when\": \"<string>\",\n \"input\": {},\n \"key\": \"<string>\",\n \"result_path\": \"<string>\",\n \"script\": \"<string>\"\n }\n ],\n \"timestamp_column\": \"<string>\",\n \"validate_only\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.erdo.ai/v1/dataset-row-actions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"after\": \"<string>\",\n \"backfill\": \"<string>\",\n \"dataset\": \"<string>\",\n \"destination\": {\n \"columns\": {},\n \"dataset\": \"<string>\",\n \"key_column\": \"<string>\"\n },\n \"enabled\": true,\n \"key_column\": \"<string>\",\n \"key_fallback_columns\": [\n \"<string>\"\n ],\n \"name\": \"<string>\",\n \"on_update\": \"<string>\",\n \"skip_when\": \"<string>\",\n \"steps\": [\n {\n \"app\": \"<string>\",\n \"fallback\": true,\n \"for_each\": {},\n \"found_when\": \"<string>\",\n \"input\": {},\n \"key\": \"<string>\",\n \"result_path\": \"<string>\",\n \"script\": \"<string>\"\n }\n ],\n \"timestamp_column\": \"<string>\",\n \"validate_only\": true\n}"
response = http.request(request)
puts response.read_body{
"after": "<string>",
"dataset": "<string>",
"destination": {
"columns": {},
"dataset": "<string>",
"key_column": "<string>"
},
"enabled": true,
"impact": {
"backfill_in_progress": true,
"backfill_requested": true,
"operation": "<string>",
"pending_run": true,
"summary": "<string>",
"would_contact_historical_rows": true,
"would_run_now": true
},
"job_id": "<string>",
"key_column": "<string>",
"key_fallback_columns": [
"<string>"
],
"name": "<string>",
"on_update": "<string>",
"skip_when": "<string>",
"steps": [
{
"app": "<string>",
"fallback": true,
"for_each": {},
"found_when": "<string>",
"input": {},
"key": "<string>",
"result_path": "<string>",
"script": "<string>"
}
],
"timestamp_column": "<string>",
"validated_only": true
}{
"code": "not_found",
"details": {},
"message": "<string>"
}Declares what happens when new rows land in a dataset: invoke an action on
each new row, and optionally record the result in another dataset. The declaration replaces whatever was previously declared under the same name; enabled false removes it.
curl --request PUT \
--url https://api.erdo.ai/v1/dataset-row-actions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"after": "<string>",
"backfill": "<string>",
"dataset": "<string>",
"destination": {
"columns": {},
"dataset": "<string>",
"key_column": "<string>"
},
"enabled": true,
"key_column": "<string>",
"key_fallback_columns": [
"<string>"
],
"name": "<string>",
"on_update": "<string>",
"skip_when": "<string>",
"steps": [
{
"app": "<string>",
"fallback": true,
"for_each": {},
"found_when": "<string>",
"input": {},
"key": "<string>",
"result_path": "<string>",
"script": "<string>"
}
],
"timestamp_column": "<string>",
"validate_only": true
}
'import requests
url = "https://api.erdo.ai/v1/dataset-row-actions"
payload = {
"after": "<string>",
"backfill": "<string>",
"dataset": "<string>",
"destination": {
"columns": {},
"dataset": "<string>",
"key_column": "<string>"
},
"enabled": True,
"key_column": "<string>",
"key_fallback_columns": ["<string>"],
"name": "<string>",
"on_update": "<string>",
"skip_when": "<string>",
"steps": [
{
"app": "<string>",
"fallback": True,
"for_each": {},
"found_when": "<string>",
"input": {},
"key": "<string>",
"result_path": "<string>",
"script": "<string>"
}
],
"timestamp_column": "<string>",
"validate_only": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
after: '<string>',
backfill: '<string>',
dataset: '<string>',
destination: {columns: {}, dataset: '<string>', key_column: '<string>'},
enabled: true,
key_column: '<string>',
key_fallback_columns: ['<string>'],
name: '<string>',
on_update: '<string>',
skip_when: '<string>',
steps: [
{
app: '<string>',
fallback: true,
for_each: {},
found_when: '<string>',
input: {},
key: '<string>',
result_path: '<string>',
script: '<string>'
}
],
timestamp_column: '<string>',
validate_only: true
})
};
fetch('https://api.erdo.ai/v1/dataset-row-actions', 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/dataset-row-actions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'after' => '<string>',
'backfill' => '<string>',
'dataset' => '<string>',
'destination' => [
'columns' => [
],
'dataset' => '<string>',
'key_column' => '<string>'
],
'enabled' => true,
'key_column' => '<string>',
'key_fallback_columns' => [
'<string>'
],
'name' => '<string>',
'on_update' => '<string>',
'skip_when' => '<string>',
'steps' => [
[
'app' => '<string>',
'fallback' => true,
'for_each' => [
],
'found_when' => '<string>',
'input' => [
],
'key' => '<string>',
'result_path' => '<string>',
'script' => '<string>'
]
],
'timestamp_column' => '<string>',
'validate_only' => true
]),
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/dataset-row-actions"
payload := strings.NewReader("{\n \"after\": \"<string>\",\n \"backfill\": \"<string>\",\n \"dataset\": \"<string>\",\n \"destination\": {\n \"columns\": {},\n \"dataset\": \"<string>\",\n \"key_column\": \"<string>\"\n },\n \"enabled\": true,\n \"key_column\": \"<string>\",\n \"key_fallback_columns\": [\n \"<string>\"\n ],\n \"name\": \"<string>\",\n \"on_update\": \"<string>\",\n \"skip_when\": \"<string>\",\n \"steps\": [\n {\n \"app\": \"<string>\",\n \"fallback\": true,\n \"for_each\": {},\n \"found_when\": \"<string>\",\n \"input\": {},\n \"key\": \"<string>\",\n \"result_path\": \"<string>\",\n \"script\": \"<string>\"\n }\n ],\n \"timestamp_column\": \"<string>\",\n \"validate_only\": true\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.erdo.ai/v1/dataset-row-actions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"after\": \"<string>\",\n \"backfill\": \"<string>\",\n \"dataset\": \"<string>\",\n \"destination\": {\n \"columns\": {},\n \"dataset\": \"<string>\",\n \"key_column\": \"<string>\"\n },\n \"enabled\": true,\n \"key_column\": \"<string>\",\n \"key_fallback_columns\": [\n \"<string>\"\n ],\n \"name\": \"<string>\",\n \"on_update\": \"<string>\",\n \"skip_when\": \"<string>\",\n \"steps\": [\n {\n \"app\": \"<string>\",\n \"fallback\": true,\n \"for_each\": {},\n \"found_when\": \"<string>\",\n \"input\": {},\n \"key\": \"<string>\",\n \"result_path\": \"<string>\",\n \"script\": \"<string>\"\n }\n ],\n \"timestamp_column\": \"<string>\",\n \"validate_only\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.erdo.ai/v1/dataset-row-actions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"after\": \"<string>\",\n \"backfill\": \"<string>\",\n \"dataset\": \"<string>\",\n \"destination\": {\n \"columns\": {},\n \"dataset\": \"<string>\",\n \"key_column\": \"<string>\"\n },\n \"enabled\": true,\n \"key_column\": \"<string>\",\n \"key_fallback_columns\": [\n \"<string>\"\n ],\n \"name\": \"<string>\",\n \"on_update\": \"<string>\",\n \"skip_when\": \"<string>\",\n \"steps\": [\n {\n \"app\": \"<string>\",\n \"fallback\": true,\n \"for_each\": {},\n \"found_when\": \"<string>\",\n \"input\": {},\n \"key\": \"<string>\",\n \"result_path\": \"<string>\",\n \"script\": \"<string>\"\n }\n ],\n \"timestamp_column\": \"<string>\",\n \"validate_only\": true\n}"
response = http.request(request)
puts response.read_body{
"after": "<string>",
"dataset": "<string>",
"destination": {
"columns": {},
"dataset": "<string>",
"key_column": "<string>"
},
"enabled": true,
"impact": {
"backfill_in_progress": true,
"backfill_requested": true,
"operation": "<string>",
"pending_run": true,
"summary": "<string>",
"would_contact_historical_rows": true,
"would_run_now": true
},
"job_id": "<string>",
"key_column": "<string>",
"key_fallback_columns": [
"<string>"
],
"name": "<string>",
"on_update": "<string>",
"skip_when": "<string>",
"steps": [
{
"app": "<string>",
"fallback": true,
"for_each": {},
"found_when": "<string>",
"input": {},
"key": "<string>",
"result_path": "<string>",
"script": "<string>"
}
],
"timestamp_column": "<string>",
"validated_only": true
}{
"code": "not_found",
"details": {},
"message": "<string>"
}Authorizations
An Erdo API key (erdo_api_...) or scoped token (erdo_token_...).
Body
for. Both are triggered by the same write, so without it they run at the same moment and neither can see the other's work. With it, a row is held until that declaration has recorded its result for the same row, and what it recorded arrives as this declaration's starting result — so an alert can say what a lookup found. A row is never held indefinitely: if the result has not landed within a few minutes, the row is acted on without it.
Without it a declaration only ever sees what arrives next, which is the right default — declaring one must not silently invoke a paid action once per historical row — but it leaves no way to say "and do the ones you got wrong". A declaration whose steps were mistaken is otherwise permanent: every row it already decided about is remembered as decided.
"all" means every row. A timestamp means every row at or after it. Both clear the record of what has been acted on, so the rows in range are taken through the steps again even though they have been through them before — which is the entire request.
including ones created later.
normal: a step that sends an email or files a ticket has done its work by running, and has nothing to store.
Show child attributes
Show child attributes
than pausing it, so declaring it again later starts from the rows arriving then instead of working through everything that accumulated in between.
this dataset upserts on. It is how a row being written a second time is recognised as the same row rather than a new one. Normally detected; set it when the dataset identifies a row unconventionally.
dataset can both alert a desk and enrich a record without either replacing the other. Lowercase letters, digits, hyphens and underscores.
written again: "skip" (the default) leaves it alone, and "act" takes it through the steps again. Default to skip unless a later write genuinely changes the answer — acting again invokes the actions again, and pays for them again.
Each new row is judged against the caller's own words before actions run or a destination is written. An uncertain or failed judgement runs the steps: the gate fails open rather than silently dropping work.
once an earlier action has answered, and a script always runs. A step whose templated input resolves to nothing cannot be built for that row, so the next one is tried instead.
Show child attributes
Show child attributes
detected; set it when the dataset names that column unconventionally. It must hold timestamps: the declaration starts from the newest value already in that column and compares later rows against it as text, so a column of free-text answers is refused rather than accepted into a declaration that would act on nothing.
would use, then stops before it creates, updates or removes an automation, changes a trigger or standing grant, or starts a run.
Response
Success response
normal: a step that sends an email or files a ticket has done its work by running, and has nothing to store.
Show child attributes
Show child attributes
of the corresponding non-validation call.
Show child attributes
Show child attributes
history can be inspected through the automation surfaces.
Show child attributes
Show child attributes
Impact is omitted from ordinary read and write responses.

