Skip to content

Events API

The Events API exposes tracker events and event history for automation. Use it for incremental polling, internal alerting, enrichment workflows, and pivots from a company, domain, actor, country, sector, update timestamp, or event status.

GET /api/v1/events/list/
GET /api/v1/events/list/from/{from}/to/{to}/
POST /api/v1/events/list/
POST /api/v1/events/list/from/{from}/to/{to}/
GET /api/v1/events/view/{id}/
GET /api/v1/events/search/{query}/
GET /api/v1/events/search/{query}/from/{from}/to/{to}/
GET /api/v1/events/historySearch/?query={query}
GET /api/v1/events/status/{status}/
GET /api/v1/events/status/{status}/from/{from}/to/{to}/
GET /api/v1/events/updated/?since={timestamp}
GET /api/v1/events/updated/since/{timestamp}/
GET /api/v1/events/sectorGroups/
GET /api/v1/events/extensionArchive/

from and to accept the date formats supported by the live API, including YYYY-MM-DD values and UNIX timestamps where applicable. When no date range is supplied, the list endpoint returns the API’s default recent window.

Use the updated endpoint when your integration needs changes to existing events. The list endpoint filters by first_seen; the updated endpoint filters by last_update.

GET /events/list/ returns recent tracker events. Use this for simple polling when you do not need filters.

GET /events/list/from/{from}/to/{to}/ returns tracker events first seen inside the requested time range. This is the preferred endpoint for scheduled imports because your integration can store the last successful timestamp and resume from there.

POST /events/list/ and POST /events/list/from/{from}/to/{to}/ accept the same list behavior, plus optional filters in the request body. Use POST when filtering by sector, actor, domain, country, or employee count.

GET /events/view/{id}/ returns the full event object for one event ID. Use it after a list or search result when you need the complete details.

GET /events/search/{query}/ searches event data for a company, domain, title, actor, country, sector, or related metadata.

GET /events/historySearch/?query={query} searches historical event detail snapshots and post content.

GET /events/status/{status}/ returns events that received a specific status marker.

GET /events/updated/?since={timestamp} returns events whose last_update is newer than the supplied timestamp. This is the recommended endpoint for integrations that keep a local copy of eCrime.ch events and need changed records, not only newly observed records.

GET /events/sectorGroups/ returns the maintained combined sector groups that can be used with the sector_group filter.

Use this endpoint when you want records changed after a checkpoint:

GET /api/v1/events/updated/?since=2026-09-01T00:00:00Z&limit=500

The response returns the same event objects as the list endpoint, ordered by:

last_update ASC, id ASC

Supported query parameters:

  • since is required. It accepts UNIX timestamps, YYYY-MM-DD, or ISO-style timestamps such as 2026-09-01T00:00:00Z.
  • until is optional. If omitted, the API freezes the sync window at the current UTC time and returns that value in sync.until.
  • limit is optional. The default is 500; the maximum is 1000.
  • cursor is optional. Use the value from sync.next_cursor when sync.has_more is true.

For multi-page syncs, keep using the first response’s sync.until value on all following cursor requests. This prevents a long import from chasing records updated after the sync started.

First page example:

Terminal window
curl -X GET "https://ecrime.ch/api/v1/events/updated/?since=2026-09-01T00:00:00Z&limit=500" \
-H "X-API-Key: YOUR_API_KEY_HERE"

Next page example:

Terminal window
curl -X GET "https://ecrime.ch/api/v1/events/updated/?since=2026-09-01T00:00:00Z&until=2026-09-24T12:34:56Z&limit=500&cursor=2026-09-24%2009%3A15%3A00%7C42123" \
-H "X-API-Key: YOUR_API_KEY_HERE"

UNIX timestamp example:

Terminal window
SINCE="$(date -u -d '24 hours ago' +%s)"
curl -X GET "https://ecrime.ch/api/v1/events/updated/?since=${SINCE}&limit=1000" \
-H "X-API-Key: YOUR_API_KEY_HERE"

Example response shape:

{
"status": "200",
"message": "OK",
"date": 1790240000,
"results": 500,
"sync": {
"since": "2026-09-01T00:00:00Z",
"until": "2026-09-24T12:34:56Z",
"limit": 500,
"has_more": true,
"next_cursor": "2026-09-24 09:15:00|42123"
},
"data": [
{
"id": 42123,
"first_seen": "2026-08-30 10:12:00.000000+00:00",
"last_update": "2026-09-24 09:15:00.000000+00:00",
"leak_site": "ExampleActor",
"leak_title": "Example Victim Ltd",
"data_leak": 1
}
]
}

Python incremental sync example:

import os
import requests
base_url = "https://ecrime.ch/api/v1"
headers = {"X-API-Key": os.environ["ECRIME_API_KEY"]}
since = "2026-09-01T00:00:00Z"
until = None
cursor = None
while True:
params = {"since": since, "limit": 500}
if until:
params["until"] = until
if cursor:
params["cursor"] = cursor
response = requests.get(
f"{base_url}/events/updated/",
headers=headers,
params=params,
timeout=60,
)
response.raise_for_status()
payload = response.json()
if payload["status"] != "200":
raise RuntimeError(payload.get("message", "API request failed"))
sync = payload["sync"]
until = until or sync["until"]
for event in payload["data"]:
# Upsert by event["id"] in your local datastore.
print(event["id"], event["last_update"], event["leak_title"])
if not sync["has_more"]:
# Store sync["until"] as your next checkpoint after all pages succeed.
break
cursor = sync["next_cursor"]

Path-style example:

Terminal window
curl -X GET "https://ecrime.ch/api/v1/events/updated/since/2026-09-01T00:00:00Z/?limit=500" \
-H "X-API-Key: YOUR_API_KEY_HERE"

POST /events/list/ and date-range list requests support filters such as:

  • sector
  • sector_group
  • actor
  • domain
  • country
  • employees

Filters may be sent as form fields. Some integrations send repeated fields or array-style keys for multi-value filtering.

Use sector when you want to match one exact raw sector value as it appears on event objects. This is best for precise queries where your integration already knows the exact sector label, such as Hospitals and Health Care or Oil and Gas.

Use sector_group when you want a maintained broad category such as Healthcare and Medical, Finance and Insurance, or Information Technology and Services. A sector group expands server-side to its member raw sectors, so this is the safer choice for monitoring, alerting, and broad industry searches where raw sector labels may vary or change over time.

sector and sector_group can be used together. The list endpoint returns events matching either the raw sector value or any raw sector inside the requested group.

Sector groups are maintained by eCrime.ch and are exposed through:

Terminal window
curl -X GET "https://ecrime.ch/api/v1/events/sectorGroups/" \
-H "X-API-Key: YOUR_API_KEY_HERE"

Example response shape:

{
"status": "200",
"message": "OK",
"results": 1,
"data": [
{
"name": "Healthcare and Medical",
"sectors": [
"Hospitals and Health Care",
"Medical Practice",
"Pharmaceutical Manufacturing"
]
}
]
}

Example exact raw-sector POST request:

Terminal window
curl -X POST "https://ecrime.ch/api/v1/events/list/from/2026-06-01/to/2026-06-17/" \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "sector=Hospitals and Health Care"

Example combined-sector POST request:

Terminal window
curl -X POST "https://ecrime.ch/api/v1/events/list/from/2026-06-01/to/2026-06-17/" \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "sector_group=Healthcare and Medical"

Example multiple combined-sector POST request:

Terminal window
curl -X POST "https://ecrime.ch/api/v1/events/list/from/2026-06-01/to/2026-06-17/" \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "sector_group[]=Healthcare and Medical" \
--data-urlencode "sector_group[]=Finance and Insurance"

Example multi-filter POST request:

Terminal window
curl -X POST "https://ecrime.ch/api/v1/events/list/" \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "country=United States&actor=Akira&sector_group=Healthcare and Medical"

Authenticated users can add and manage their own event comments:

POST /api/v1/events/addComment/{id}/
GET /api/v1/events/deleteComment/{id}/
GET /api/v1/events/listComments/

Deleting a comment requires the comment ID, not the event ID.

Terminal window
curl -X GET "https://ecrime.ch/api/v1/events/list/from/2026-06-01/to/2026-06-17/" \
-H "X-API-Key: YOUR_API_KEY_HERE"
Terminal window
curl -X GET "https://ecrime.ch/api/v1/events/search/example.com/" \
-H "X-API-Key: YOUR_API_KEY_HERE"
{
"status": "200",
"message": "OK",
"date": 1781677568,
"results": 1,
"data": [
{
"id": 15152,
"first_seen": "2023-07-09 05:31:14.000000+00:00",
"last_seen": "2023-07-09 14:16:34.000000+00:00",
"leak_site": "8BASE",
"leak_title": "Cabra Consulting Ltd",
"country": "Canada",
"sector": "Oil and Gas",
"name": "Cabra Consulting Ltd.",
"website": "https://www.cabra.ca/",
"employees": "11-50 employees",
"revenue": "$5 Million",
"stock_symbol": null,
"leak_url": "http://example.onion/company/7890167",
"duplicate": null,
"data_leak": 0,
"last_update": "2023-07-09 05:32:34.000000+00:00",
"logo": "https://ecrime.ch/image/logos/example.jpg",
"keyword": "false",
"links": [
{
"url": "https://www.cabra.ca/security-notice/",
"title": "Security Notice",
"date": "2023-07-09"
}
],
"status": [
{
"name": "initial",
"date": 1688913874
},
{
"name": "enriched",
"date": 1688914200
}
]
}
]
}

The response envelope is stable across endpoints. results is the number of returned items, and data contains event objects. Event objects may include nullable enrichment fields when no company match or enrichment value exists yet.

Common status filters include:

  • initial
  • enriched
  • data_leak
  • screenshot
  • comment_added
  • comment_deleted
  • dls_removed