Correct many data point values
Applies many corrections in one all-or-nothing request. Each item speaks the same shape as a single correction and addresses its data point by event ID and slug, so one call can span many events and event types.
If any item fails, nothing is persisted. The response still reports every item so you can find the bad one: failing items carry status: "error" with a message, and items that would have succeeded come back as not_applied. Fix the reported item and resend the whole batch.
A not_applied item still carries a populated correction object, describing the change that was rolled back. Its id refers to a record that was never persisted, so do not store it or use it in a later request.
Requires corrections to be enabled on the account.
curl --request POST \
--url https://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"corrections": [
{
"event": "evt_DLnYvzbjSujNAvXE",
"slug": "ambient-temperature-c",
"value": 12.4,
"notes": "Sensor drift confirmed against the calibration log."
},
{
"event": "evt_7nxaDUf65c36v6mz",
"slug": "mass-flow-rate",
"value": 0,
"method": "zero_fill",
"expect": "gap"
}
]
}
'import requests
url = "https://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch"
payload = { "corrections": [
{
"event": "evt_DLnYvzbjSujNAvXE",
"slug": "ambient-temperature-c",
"value": 12.4,
"notes": "Sensor drift confirmed against the calibration log."
},
{
"event": "evt_7nxaDUf65c36v6mz",
"slug": "mass-flow-rate",
"value": 0,
"method": "zero_fill",
"expect": "gap"
}
] }
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
corrections: [
{
event: 'evt_DLnYvzbjSujNAvXE',
slug: 'ambient-temperature-c',
value: 12.4,
notes: 'Sensor drift confirmed against the calibration log.'
},
{
event: 'evt_7nxaDUf65c36v6mz',
slug: 'mass-flow-rate',
value: 0,
method: 'zero_fill',
expect: 'gap'
}
]
})
};
fetch('https://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch', 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://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch",
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([
'corrections' => [
[
'event' => 'evt_DLnYvzbjSujNAvXE',
'slug' => 'ambient-temperature-c',
'value' => 12.4,
'notes' => 'Sensor drift confirmed against the calibration log.'
],
[
'event' => 'evt_7nxaDUf65c36v6mz',
'slug' => 'mass-flow-rate',
'value' => 0,
'method' => 'zero_fill',
'expect' => 'gap'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"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://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch"
payload := strings.NewReader("{\n \"corrections\": [\n {\n \"event\": \"evt_DLnYvzbjSujNAvXE\",\n \"slug\": \"ambient-temperature-c\",\n \"value\": 12.4,\n \"notes\": \"Sensor drift confirmed against the calibration log.\"\n },\n {\n \"event\": \"evt_7nxaDUf65c36v6mz\",\n \"slug\": \"mass-flow-rate\",\n \"value\": 0,\n \"method\": \"zero_fill\",\n \"expect\": \"gap\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
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://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"corrections\": [\n {\n \"event\": \"evt_DLnYvzbjSujNAvXE\",\n \"slug\": \"ambient-temperature-c\",\n \"value\": 12.4,\n \"notes\": \"Sensor drift confirmed against the calibration log.\"\n },\n {\n \"event\": \"evt_7nxaDUf65c36v6mz\",\n \"slug\": \"mass-flow-rate\",\n \"value\": 0,\n \"method\": \"zero_fill\",\n \"expect\": \"gap\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"corrections\": [\n {\n \"event\": \"evt_DLnYvzbjSujNAvXE\",\n \"slug\": \"ambient-temperature-c\",\n \"value\": 12.4,\n \"notes\": \"Sensor drift confirmed against the calibration log.\"\n },\n {\n \"event\": \"evt_7nxaDUf65c36v6mz\",\n \"slug\": \"mass-flow-rate\",\n \"value\": 0,\n \"method\": \"zero_fill\",\n \"expect\": \"gap\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"applied": true,
"results": [
{
"index": 0,
"status": "created",
"correction": {
"id": "sub_9TnpQxL2mKdRvWs4",
"data_point_id": "in_kiIuaGIUqRxWUmTY",
"stage": "ingestion",
"source": "api",
"method": "manual_entry",
"origin": "substituted",
"from_value": 14.9,
"to_value": 12.4,
"notes": "Sensor drift confirmed against the calibration log.",
"rule": null,
"created_by": "Aaron Rosenberg",
"created_at": "2026-07-21T14:02:55.000Z"
}
},
{
"index": 1,
"status": "unchanged",
"correction": {
"id": "sub_Lp7m2XcQd0RtVbnm",
"data_point_id": "in_JuGzRS08MbVSEkCj",
"stage": "ingestion",
"source": "api",
"method": "zero_fill",
"origin": "imputed",
"from_value": null,
"to_value": 0,
"notes": null,
"rule": null,
"created_by": "Aaron Rosenberg",
"created_at": "2026-07-20T11:30:00.000Z"
}
}
]
}Authorizations
Path Parameters
Body
The corrections to apply, in order. Each item is reported back by its index.
Show child attributes
Show child attributes
curl --request POST \
--url https://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"corrections": [
{
"event": "evt_DLnYvzbjSujNAvXE",
"slug": "ambient-temperature-c",
"value": 12.4,
"notes": "Sensor drift confirmed against the calibration log."
},
{
"event": "evt_7nxaDUf65c36v6mz",
"slug": "mass-flow-rate",
"value": 0,
"method": "zero_fill",
"expect": "gap"
}
]
}
'import requests
url = "https://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch"
payload = { "corrections": [
{
"event": "evt_DLnYvzbjSujNAvXE",
"slug": "ambient-temperature-c",
"value": 12.4,
"notes": "Sensor drift confirmed against the calibration log."
},
{
"event": "evt_7nxaDUf65c36v6mz",
"slug": "mass-flow-rate",
"value": 0,
"method": "zero_fill",
"expect": "gap"
}
] }
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
corrections: [
{
event: 'evt_DLnYvzbjSujNAvXE',
slug: 'ambient-temperature-c',
value: 12.4,
notes: 'Sensor drift confirmed against the calibration log.'
},
{
event: 'evt_7nxaDUf65c36v6mz',
slug: 'mass-flow-rate',
value: 0,
method: 'zero_fill',
expect: 'gap'
}
]
})
};
fetch('https://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch', 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://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch",
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([
'corrections' => [
[
'event' => 'evt_DLnYvzbjSujNAvXE',
'slug' => 'ambient-temperature-c',
'value' => 12.4,
'notes' => 'Sensor drift confirmed against the calibration log.'
],
[
'event' => 'evt_7nxaDUf65c36v6mz',
'slug' => 'mass-flow-rate',
'value' => 0,
'method' => 'zero_fill',
'expect' => 'gap'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"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://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch"
payload := strings.NewReader("{\n \"corrections\": [\n {\n \"event\": \"evt_DLnYvzbjSujNAvXE\",\n \"slug\": \"ambient-temperature-c\",\n \"value\": 12.4,\n \"notes\": \"Sensor drift confirmed against the calibration log.\"\n },\n {\n \"event\": \"evt_7nxaDUf65c36v6mz\",\n \"slug\": \"mass-flow-rate\",\n \"value\": 0,\n \"method\": \"zero_fill\",\n \"expect\": \"gap\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
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://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"corrections\": [\n {\n \"event\": \"evt_DLnYvzbjSujNAvXE\",\n \"slug\": \"ambient-temperature-c\",\n \"value\": 12.4,\n \"notes\": \"Sensor drift confirmed against the calibration log.\"\n },\n {\n \"event\": \"evt_7nxaDUf65c36v6mz\",\n \"slug\": \"mass-flow-rate\",\n \"value\": 0,\n \"method\": \"zero_fill\",\n \"expect\": \"gap\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.gomangrove.com/api/v1/projects/{project_id}/corrections/batch")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"corrections\": [\n {\n \"event\": \"evt_DLnYvzbjSujNAvXE\",\n \"slug\": \"ambient-temperature-c\",\n \"value\": 12.4,\n \"notes\": \"Sensor drift confirmed against the calibration log.\"\n },\n {\n \"event\": \"evt_7nxaDUf65c36v6mz\",\n \"slug\": \"mass-flow-rate\",\n \"value\": 0,\n \"method\": \"zero_fill\",\n \"expect\": \"gap\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"applied": true,
"results": [
{
"index": 0,
"status": "created",
"correction": {
"id": "sub_9TnpQxL2mKdRvWs4",
"data_point_id": "in_kiIuaGIUqRxWUmTY",
"stage": "ingestion",
"source": "api",
"method": "manual_entry",
"origin": "substituted",
"from_value": 14.9,
"to_value": 12.4,
"notes": "Sensor drift confirmed against the calibration log.",
"rule": null,
"created_by": "Aaron Rosenberg",
"created_at": "2026-07-21T14:02:55.000Z"
}
},
{
"index": 1,
"status": "unchanged",
"correction": {
"id": "sub_Lp7m2XcQd0RtVbnm",
"data_point_id": "in_JuGzRS08MbVSEkCj",
"stage": "ingestion",
"source": "api",
"method": "zero_fill",
"origin": "imputed",
"from_value": null,
"to_value": 0,
"notes": null,
"rule": null,
"created_by": "Aaron Rosenberg",
"created_at": "2026-07-20T11:30:00.000Z"
}
}
]
}