curl --request GET \
--url https://app.chainpatrol.io/api/v2/organization/reports \
--header 'X-API-KEY: <api-key>'{
"reports": [
{
"id": 123,
"title": "<string>",
"description": "<string>",
"status": "TODO",
"createdAt": "<string>",
"updatedAt": "<string>",
"attachments": [
{
"id": 123,
"url": "<string>"
}
],
"proposals": [
{
"reviewStatus": "PENDING",
"asset": {
"id": 123,
"type": "URL",
"content": "<string>",
"status": "UNKNOWN",
"scans": [
{
"id": 123,
"status": "PENDING",
"createdAt": "<string>",
"enrichments": [
{
"id": 123,
"type": "<string>",
"status": "<string>",
"output": null
}
],
"output": null
}
]
}
}
],
"reporter": {
"id": 123,
"role": "SUPERUSER",
"fullName": "<string>",
"avatarUrl": "<string>"
},
"externalReporter": {
"id": 123,
"displayName": "<string>",
"avatarUrl": "<string>",
"platform": "<string>"
}
}
],
"nextCursor": 123
}List all reports belonging to your organization with optional filtering and pagination. Organization is determined from your API key.
curl --request GET \
--url https://app.chainpatrol.io/api/v2/organization/reports \
--header 'X-API-KEY: <api-key>'{
"reports": [
{
"id": 123,
"title": "<string>",
"description": "<string>",
"status": "TODO",
"createdAt": "<string>",
"updatedAt": "<string>",
"attachments": [
{
"id": 123,
"url": "<string>"
}
],
"proposals": [
{
"reviewStatus": "PENDING",
"asset": {
"id": 123,
"type": "URL",
"content": "<string>",
"status": "UNKNOWN",
"scans": [
{
"id": 123,
"status": "PENDING",
"createdAt": "<string>",
"enrichments": [
{
"id": 123,
"type": "<string>",
"status": "<string>",
"output": null
}
],
"output": null
}
]
}
}
],
"reporter": {
"id": 123,
"role": "SUPERUSER",
"fullName": "<string>",
"avatarUrl": "<string>"
},
"externalReporter": {
"id": 123,
"displayName": "<string>",
"avatarUrl": "<string>",
"platform": "<string>"
}
}
],
"nextCursor": 123
}X-API-KEY header:
X-API-KEY: your_api_key_here
const response = await fetch(
"https://app.chainpatrol.io/api/v2/organization/reports?limit=50",
{
method: "GET",
headers: {
"X-API-KEY": "YOUR_API_KEY_HERE",
},
}
);
const data = await response.json();
console.log(data.reports);
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | number | No | Number of reports to return per page (1-100, default: 50) |
| cursor | string | No | Cursor for pagination. Pass the cursor from the previous response to get the next page. |
| startDate | string | No | Filter reports created after this date (ISO 8601 format) |
| endDate | string | No | Filter reports created before this date (ISO 8601 format) |
| onlyRejected | boolean | No | If true, only return reports with rejected proposals (default: false) |
{
"reports": [
{
"id": "rpt_1234567890abcdef",
"createdAt": "2024-01-15T10:30:00.000Z",
"status": "APPROVED",
"assets": [
{
"id": 12345,
"content": "https://scam-site.com",
"type": "URL",
"status": "BLOCKED"
}
],
"proposals": [
{
"id": "prop_abc123",
"status": "APPROVED",
"reason": "phishing",
"createdAt": "2024-01-15T10:30:00.000Z"
}
]
}
],
"cursor": "next_page_cursor_string"
}
| Field | Type | Description |
|---|---|---|
| reports | array | Array of report objects for your organization |
| reports[].id | string | Unique identifier for the report |
| reports[].createdAt | string | ISO 8601 timestamp when the report was created |
| reports[].status | string | Overall status of the report (PENDING, APPROVED, REJECTED) |
| reports[].assets | array | Array of assets included in the report |
| reports[].proposals | array | Array of proposals associated with the report |
| cursor | string | Cursor for the next page of results (undefined if no more results) |
async function fetchAllReports() {
let allReports = [];
let cursor: string | undefined = undefined;
while (true) {
const params = new URLSearchParams({
limit: "100",
...(cursor && { cursor }),
});
const response = await fetch(
`https://app.chainpatrol.io/api/v2/organization/reports?${params}`,
{
method: "GET",
headers: {
"X-API-KEY": "YOUR_API_KEY_HERE",
},
}
);
const data = await response.json();
allReports = allReports.concat(data.reports);
cursor = data.cursor;
if (!cursor) {
break;
}
}
return allReports;
}
fetchAllReports()
.then((reports) => console.log(`Total reports: ${reports.length}`))
.catch((error) => console.error("Error:", error));
curl -X GET 'https://app.chainpatrol.io/api/v2/organization/reports?startDate=2024-01-01T00:00:00Z&endDate=2024-03-31T23:59:59Z' \
-H 'X-API-KEY: YOUR_API_KEY_HERE'
curl -X GET 'https://app.chainpatrol.io/api/v2/organization/reports?onlyRejected=true' \
-H 'X-API-KEY: YOUR_API_KEY_HERE'
curl -X GET 'https://app.chainpatrol.io/api/v2/organization/reports?startDate=2024-01-01T00:00:00Z&endDate=2024-03-31T23:59:59Z&onlyRejected=true&limit=100' \
-H 'X-API-KEY: YOUR_API_KEY_HERE'
{
"error": {
"code": "UNAUTHORIZED",
"message": "API key with organization access required"
}
}
{
"error": {
"code": "BAD_REQUEST",
"message": "Invalid date format. Use ISO 8601 format."
}
}
async function getRecentReports(days: number = 7) {
const startDate = new Date();
startDate.setDate(startDate.getDate() - days);
const response = await fetch(
`https://app.chainpatrol.io/api/v2/organization/reports?startDate=${startDate.toISOString()}&limit=100`,
{
headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
}
);
const { reports } = await response.json();
console.log(`Found ${reports.length} reports in the last ${days} days`);
return reports;
}
async function analyzeRejectedReports() {
const response = await fetch(
"https://app.chainpatrol.io/api/v2/organization/reports?onlyRejected=true",
{
headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
}
);
const { reports } = await response.json();
// Analyze rejection reasons
const rejectionReasons = reports.flatMap((report) =>
report.proposals
.filter((p) => p.status === "REJECTED")
.map((p) => p.rejectionReason)
);
console.log("Common rejection reasons:", rejectionReasons);
return rejectionReasons;
}
async function exportReportsToCSV(startDate: string, endDate: string) {
const response = await fetch(
`https://app.chainpatrol.io/api/v2/organization/reports?startDate=${startDate}&endDate=${endDate}&limit=100`,
{
headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
}
);
const { reports } = await response.json();
const csvHeader = "Report ID,Created At,Status,Assets,Proposals\n";
const csvRows = reports
.map(
(r) =>
`${r.id},${r.createdAt},${r.status},${r.assets.length},${r.proposals.length}`
)
.join("\n");
const csv = csvHeader + csvRows;
// Save or return CSV
return csv;
}
limit=100 for bulk data retrieval to minimize API callscursor field to determine if more results existYYYY-MM-DDTHH:mm:ss.sssZZ suffix)startDate and endDate for precise time rangesonlyRejected filter shows reports with at least one rejected proposal, but the report may contain other approved proposalsYour API key. This is required by most endpoints to access our API programatically. Reach out to us at support@chainpatrol.io to get an API key for your use.
1 <= x <= 20TODO, IN_PROGRESS, CLOSED APPROVE, REJECT, SKIP, ESCALATE Was this page helpful?