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.
Endpoints
Section titled “Endpoints”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.
Endpoint Details
Section titled “Endpoint Details”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.
Updated Events and Incremental Sync
Section titled “Updated Events and Incremental Sync”Use this endpoint when you want records changed after a checkpoint:
GET /api/v1/events/updated/?since=2026-09-01T00:00:00Z&limit=500The response returns the same event objects as the list endpoint, ordered by:
last_update ASC, id ASCSupported query parameters:
sinceis required. It accepts UNIX timestamps,YYYY-MM-DD, or ISO-style timestamps such as2026-09-01T00:00:00Z.untilis optional. If omitted, the API freezes the sync window at the current UTC time and returns that value insync.until.limitis optional. The default is500; the maximum is1000.cursoris optional. Use the value fromsync.next_cursorwhensync.has_moreistrue.
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:
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:
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:
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 osimport requests
base_url = "https://ecrime.ch/api/v1"headers = {"X-API-Key": os.environ["ECRIME_API_KEY"]}
since = "2026-09-01T00:00:00Z"until = Nonecursor = 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:
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"Filters
Section titled “Filters”POST /events/list/ and date-range list requests support filters such as:
sectorsector_groupactordomaincountryemployees
Filters may be sent as form fields. Some integrations send repeated fields or array-style keys for multi-value filtering.
Sector vs. Sector Group
Section titled “Sector vs. Sector Group”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:
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:
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:
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:
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:
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§or_group=Healthcare and Medical"Comments
Section titled “Comments”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.
GET Example
Section titled “GET Example”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"Search Example
Section titled “Search Example”curl -X GET "https://ecrime.ch/api/v1/events/search/example.com/" \ -H "X-API-Key: YOUR_API_KEY_HERE"Sample Response
Section titled “Sample Response”{ "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.
Status Values
Section titled “Status Values”Common status filters include:
initialenricheddata_leakscreenshotcomment_addedcomment_deleteddls_removed