Update leak status
curl --request POST \
--url https://api.projectdiscovery.io/v1/leaks/status \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"leakid": "<string>",
"leakids": [
"<string>"
]
}
'import requests
url = "https://api.projectdiscovery.io/v1/leaks/status"
payload = {
"leakid": "<string>",
"leakids": ["<string>"]
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({leakid: '<string>', leakids: ['<string>']})
};
fetch('https://api.projectdiscovery.io/v1/leaks/status', 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.projectdiscovery.io/v1/leaks/status",
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([
'leakid' => '<string>',
'leakids' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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.projectdiscovery.io/v1/leaks/status"
payload := strings.NewReader("{\n \"leakid\": \"<string>\",\n \"leakids\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<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://api.projectdiscovery.io/v1/leaks/status")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"leakid\": \"<string>\",\n \"leakids\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.projectdiscovery.io/v1/leaks/status")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"leakid\": \"<string>\",\n \"leakids\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"status": "<string>",
"message": "<string>",
"leak_id": "<string>",
"new_status": "fixed"
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}{
"message": "Access denied: you don't have access to this leak"
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}Leaks
Update leak status
Mark leaks as fixed or reopen them. Requires authentication and domain verification for employee/customer leaks. See Domain Verification for setup instructions.
POST
/
v1
/
leaks
/
status
Update leak status
curl --request POST \
--url https://api.projectdiscovery.io/v1/leaks/status \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"leakid": "<string>",
"leakids": [
"<string>"
]
}
'import requests
url = "https://api.projectdiscovery.io/v1/leaks/status"
payload = {
"leakid": "<string>",
"leakids": ["<string>"]
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({leakid: '<string>', leakids: ['<string>']})
};
fetch('https://api.projectdiscovery.io/v1/leaks/status', 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.projectdiscovery.io/v1/leaks/status",
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([
'leakid' => '<string>',
'leakids' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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.projectdiscovery.io/v1/leaks/status"
payload := strings.NewReader("{\n \"leakid\": \"<string>\",\n \"leakids\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<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://api.projectdiscovery.io/v1/leaks/status")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"leakid\": \"<string>\",\n \"leakids\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.projectdiscovery.io/v1/leaks/status")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"leakid\": \"<string>\",\n \"leakids\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"status": "<string>",
"message": "<string>",
"leak_id": "<string>",
"new_status": "fixed"
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}{
"message": "Access denied: you don't have access to this leak"
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}Overview
Update the status of one or more leaks to track remediation progress. You can mark leaks asfixed when credentials have been changed or open if they need attention.
Authentication & Authorization
Access Control
- Personal leaks: Always accessible if the leak belongs to your email
- Employee/Customer leaks: Requires domain verification for the associated domain
- Bulk operations: All specified leaks must be accessible to your account
Privacy-First Validation
The API validates leak ownership before allowing status updates to ensure users can only modify leaks they have access to.Request Body
You can update a single leak or multiple leaks in one request:Single Leak Update
{
"leakid": "b3652f2555841f7652badd9804859f4e",
"status": "fixed"
}
Multiple Leaks Update
{
"leakids": [
"b3652f2555841f7652badd9804859f4e",
"c4763g3666952g8763caee0915960g5f",
"d5874h4777063h9874dbff1026071h6g"
],
"status": "fixed"
}
Status Values
| Status | Description |
|---|---|
open | Leak requires attention - credentials may still be compromised |
fixed | Leak has been remediated - credentials have been changed/secured |
Response Examples
Successful Update
{
"status": "success",
"message": "Leak status updated successfully",
"leak_id": "b3652f2555841f7652badd9804859f4e",
"new_status": "fixed"
}
Bulk Update Success
{
"status": "success",
"message": "3 leak statuses updated successfully",
"updated_count": 3
}
Error Responses
Invalid Request Body
{
"message": "Invalid request body"
}
Access Denied
{
"message": "Access denied: you don't have access to this leak"
}
Leak Not Found
{
"message": "One or more leaks not found"
}
Validation Rules
Required Fields
- Either
leakid(single) ORleakids(multiple) must be provided statusfield is required and must be either"open"or"fixed"
Leak ID Format
- Must be 32-character MD5 hash (e.g.,
b3652f2555841f7652badd9804859f4e) - Invalid format will result in a 400 error
Ownership Validation
- API validates that you have access to each leak before updating
- Unauthorized leaks will result in a 403 error
Usage Examples
Mark single leak as fixed
curl -X POST "https://api.projectdiscovery.io/v1/leaks/status" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"leakid": "b3652f2555841f7652badd9804859f4e",
"status": "fixed"
}'
Mark multiple leaks as fixed
curl -X POST "https://api.projectdiscovery.io/v1/leaks/status" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"leakids": [
"b3652f2555841f7652badd9804859f4e",
"c4763g3666952g8763caee0915960g5f"
],
"status": "fixed"
}'
Reopen a previously fixed leak
curl -X POST "https://api.projectdiscovery.io/v1/leaks/status" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"leakid": "b3652f2555841f7652badd9804859f4e",
"status": "open"
}'
Best Practices
Remediation Workflow
- Identify leaks using the main leaks endpoint
- Get detailed info using the leak info endpoint
- Change credentials on the affected service
- Mark as fixed using this status endpoint
- Monitor for new leaks regularly
Bulk Operations
- Use bulk updates when fixing multiple related leaks
- Validate all leak IDs before making bulk requests
- Handle partial failures gracefully in bulk operations
Status Management
- Mark leaks as
fixedonly after confirming credential changes - Use
openstatus to flag leaks that need immediate attention - Regularly audit fixed leaks to ensure they remain secure
Error Handling
- Implement retry logic for transient failures
- Log access denied errors for security monitoring
- Validate leak ID format before making requests
Was this page helpful?