Redact Events API
Security Requirements and Controls
Change data deletion permissionspermissionChangeDataDeletionPermissionsAPI permission
Falcon LogScale has support for redacting individual events from the compressed segment files.
The redactEvents() API is intended to support removal of a small number of events from LogScale, enabling you to eliminate specific events that must be removed. For example:
Removing Personally Identifiable Information (PII) (for example, due to a GDPR request)
Removing accidentally logged passwords
Removing confidential data
Important
Data in system repositories cannot be redacted.
Note
Note that the start and end timestamps in a redaction request are used to create a time interval based on the @timestamp of the events. This is comparable to a time interval selection, such as you would carry out in the LogScale UI. See also Parsing Timestamps for more details.
The redaction API does not guarantee that redacting events will recover disk space, and is not intended to support data management or bulk deletion.
Important
If you want to bulk delete data, you may want to set Data Retention, or use the GraphQL API to delete the relevant dataspaces or datasources.
The redaction mechanism works by:
Initially excluding the events you mark for redaction from future queries by filtering all query results
Once LogScale determines that it is safe to do so, it will rewrite the affected segments, excluding the events that were marked for redaction.
LogScale decides that segments can be rewritten/deleted, based on the following settings:
DELETES_DELAY_MILLISis a hard minimum delay on redactions.FLUSH_BLOCK_SECONDSis added, to enable any minisegments to be merged.
The rewrite begins once FLUSH_BLOCK_SECONDS +
DELETES_DELAY_MILLIS has elapsed since the redaction was
requested.
Once the rewrite begins, it may be delayed for any of the following reasons:
A minisegment is present in the list of segments to rewrite. LogScale waits for that minisegment to be merged
A segment is present that is not yet properly replicated (that is, it is shown as "low" in the cluster admin panel)
Restarts in the cluster while the rewrite is pending
If delays occur, LogScale may delay the rewriting for a day before trying again.
Important
As rewriting segments is an expensive operation, we strongly discourage using this API in cases for which appropriate retention settings, or explicit deletions of dataspaces, would suffice.
Note
Field Aliasing is not enabled when using deletion filter queries. Ensure that you are not using aliased fields in the filter query executed through this API. For more information, see Searches with Query Prefixes.
Submitting a Redaction Request
The redactEvents() GraphQL mutation can be used to submit deletions.
This is an example redacting all events with a password field in the specified time interval in milliseconds.
mutation {
redactEvents(
input: {
repositoryName: "humio",
start: "2025-11-12T03:00:00.000Z",
end: "2025-11-12T03:15:00.000Z",
query: "password=*",
userMessage: "Hiding Passwords"
}
)
}curl -v -X POST $YOUR_LOGSCALE_URL/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d @- << EOF
{"query" : "mutation {
redactEvents(
input: {
repositoryName: \"humio\",
start: \"2025-11-12T03:00:00.000Z\",
end: \"2025-11-12T03:15:00.000Z\",
query: \"password=*\",
userMessage: \"Hiding Passwords\"
}
)
}"
}
EOFcurl -v -X POST $YOUR_LOGSCALE_URL/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d @- << EOF
{"query" : "mutation {
redactEvents(
input: {
repositoryName: \"humio\",
start: \"2025-11-12T03:00:00.000Z\",
end: \"2025-11-12T03:15:00.000Z\",
query: \"password=*\",
userMessage: \"Hiding Passwords\"
}
)
}"
}
EOFcurl -v -X POST $YOUR_LOGSCALE_URL/graphql ^
-H "Authorization: Bearer $TOKEN" ^
-H "Content-Type: application/json" ^
-d @'{"query" : "mutation { ^
redactEvents( ^
input: { ^
repositoryName: \"humio\", ^
start: \"2025-11-12T03:00:00.000Z\", ^
end: \"2025-11-12T03:15:00.000Z\", ^
query: \"password=*\", ^
userMessage: \"Hiding Passwords\" ^
} ^
) ^
}" ^
} 'curl.exe -X POST
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"query" : "mutation {
redactEvents(
input: {
repositoryName: \"humio\",
start: \"2025-11-12T03:00:00.000Z\",
end: \"2025-11-12T03:15:00.000Z\",
query: \"password=*\",
userMessage: \"Hiding Passwords\"
}
)
}"
}'
"$YOUR_LOGSCALE_URL/graphql"#!/usr/bin/perl
use HTTP::Request;
use LWP;
my $TOKEN = "TOKEN";
my $uri = '$YOUR_LOGSCALE_URL/graphql';
my $query = "mutation {
redactEvents(
input: {
repositoryName: \"humio\",
start: \"2025-11-12T03:00:00.000Z\",
end: \"2025-11-12T03:15:00.000Z\",
query: \"password=*\",
userMessage: \"Hiding Passwords\"
}
)
}";
$query =~ s/\n/ /g;
my $json = sprintf('{"query" : "%s"}',$query);
my $req = HTTP::Request->new("POST", $uri );
$req->header("Authorization" => "Bearer $TOKEN");
$req->header("Content-Type" => "application/json");
$req->content( $json );
my $lwp = LWP::UserAgent->new;
my $result = $lwp->request( $req );
print $result->{"_content"},"\n";#! /usr/local/bin/python3
import requests
url = '$YOUR_LOGSCALE_URL/graphql'
mydata = r'''{"query" : "mutation {
redactEvents(
input: {
repositoryName: \"humio\",
start: \"2025-11-12T03:00:00.000Z\",
end: \"2025-11-12T03:15:00.000Z\",
query: \"password=*\",
userMessage: \"Hiding Passwords\"
}
)
}"
}'''
resp = requests.post(url,
data = mydata,
headers = {
"Authorization" : "Bearer $TOKEN",
"Content-Type" : "application/json"
}
)
print(resp.text)const https = require('https');
const data = JSON.stringify(
{"query" : "mutation {
redactEvents(
input: {
repositoryName: \"humio\",
start: \"2025-11-12T03:00:00.000Z\",
end: \"2025-11-12T03:15:00.000Z\",
query: \"password=*\",
userMessage: \"Hiding Passwords\"
}
)
}"
}
);
const options = {
hostname: '$YOUR_LOGSCALE_URL',
path: 'graphql',
port: 443,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length,
Authorization: 'BEARER ' + process.env.TOKEN,
'User-Agent': 'Node',
},
};
const req = https.request(options, (res) => {
let data = '';
console.log(`statusCode: ${res.statusCode}`);
res.on('data', (d) => {
data += d;
});
res.on('end', () => {
console.log(JSON.parse(data).data);
});
});
req.on('error', (error) => {
console.error(error);
});
req.write(data);
req.end();{
"data": {
"redactEvents": "abc123"
}
}The mutation will return the ID of the submitted redaction task:
{
"data" : {
"redactEvents" : "e4G6TWjXVxbNyF5hDLrvBJAV"
}
}Viewing Existing Requests
The redactEvents() GraphQL query will return the list of redaction tasks that have not yet completed segment rewrites.
query {
redactEvents(repositoryName:"humio")
{ id, created,
start, end, query,
languageVersion{version} }
}curl -v -X POST $YOUR_LOGSCALE_URL/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d @- << EOF
{"query" : "query {
redactEvents(repositoryName:\"humio\")
{ id, created,
start, end, query,
languageVersion{version} }
}"
}
EOFcurl -v -X POST $YOUR_LOGSCALE_URL/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d @- << EOF
{"query" : "query {
redactEvents(repositoryName:\"humio\")
{ id, created,
start, end, query,
languageVersion{version} }
}"
}
EOFcurl -v -X POST $YOUR_LOGSCALE_URL/graphql ^
-H "Authorization: Bearer $TOKEN" ^
-H "Content-Type: application/json" ^
-d @'{"query" : "query { ^
redactEvents(repositoryName:\"humio\") ^
{ id, created, ^
start, end, query, ^
languageVersion{version} } ^
}" ^
} 'curl.exe -X POST
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"query" : "query {
redactEvents(repositoryName:\"humio\")
{ id, created,
start, end, query,
languageVersion{version} }
}"
}'
"$YOUR_LOGSCALE_URL/graphql"#!/usr/bin/perl
use HTTP::Request;
use LWP;
my $TOKEN = "TOKEN";
my $uri = '$YOUR_LOGSCALE_URL/graphql';
my $query = "query {
redactEvents(repositoryName:\"humio\")
{ id, created,
start, end, query,
languageVersion{version} }
}";
$query =~ s/\n/ /g;
my $json = sprintf('{"query" : "%s"}',$query);
my $req = HTTP::Request->new("POST", $uri );
$req->header("Authorization" => "Bearer $TOKEN");
$req->header("Content-Type" => "application/json");
$req->content( $json );
my $lwp = LWP::UserAgent->new;
my $result = $lwp->request( $req );
print $result->{"_content"},"\n";#! /usr/local/bin/python3
import requests
url = '$YOUR_LOGSCALE_URL/graphql'
mydata = r'''{"query" : "query {
redactEvents(repositoryName:\"humio\")
{ id, created,
start, end, query,
languageVersion{version} }
}"
}'''
resp = requests.post(url,
data = mydata,
headers = {
"Authorization" : "Bearer $TOKEN",
"Content-Type" : "application/json"
}
)
print(resp.text)const https = require('https');
const data = JSON.stringify(
{"query" : "query {
redactEvents(repositoryName:\"humio\")
{ id, created,
start, end, query,
languageVersion{version} }
}"
}
);
const options = {
hostname: '$YOUR_LOGSCALE_URL',
path: 'graphql',
port: 443,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length,
Authorization: 'BEARER ' + process.env.TOKEN,
'User-Agent': 'Node',
},
};
const req = https.request(options, (res) => {
let data = '';
console.log(`statusCode: ${res.statusCode}`);
res.on('data', (d) => {
data += d;
});
res.on('end', () => {
console.log(JSON.parse(data).data);
});
});
req.on('error', (error) => {
console.error(error);
});
req.write(data);
req.end();{
"data": {
"redactEvents": [
{
"id": "abc123",
"created": 1729603406707,
"start": 1729781206587,
"end": null,
"query": { "arguments": [] }
languageVersion: {"version": legacy}
}
]
}
}Returns:
{
"data" : {
"redactEvents" : "e4G6TWjXVxbNyF5hDLrvBJAV"
}
}It is possible to cancel submitted redactions via the cancelRedactEvents() mutation.
Cancellation is best-effort, and if events have already been redacted from segments, they will not be restored.
Field Aliasing is not enabled when using a deletion filter query, meaning that aliased fields won't be available for queries executed through this API. Ensure that you are not using aliased fields in the filter query used with the API. For more information, see Searches with Query Prefixes.