---
title: "Map the filtered es-python events as sources, files and the sinks they reached"
method: POST
path: "/api/event_map/"
tags: ["Events"]
---

# Map the filtered es-python events as sources, files and the sinks they reached

`POST /api/event_map/`

## Request

- Base URL: `https://eyalsec.com`
- URL: `https://eyalsec.com/api/event_map/`
- Auth: one of:
  - API key in header `X-API-Key`
  - API key in cookie `__Host-es2session`

Takes the SAME body as /api/get_all_events_with_count/, with view python, and returns the whole filtered set aggregated into a graph instead of a page of rows. This is what the events page's Map layout draws. Every event is counted under the source category the sources filter would select it with (socket, file, stdin, env, argv, manual, fuzzer, foreign, or other for an origin none of those claim), under the file it was read from when that source is file, and under its sink (the where field). sources, files and sinks list each of those, and links lists every source, file and sink path; each entry carries events (stored events), hits (the occurrences those events coalesce) and severity (the worst among them), worst first. file is empty on a link whose source is not file, and a file path is empty for a file read through a descriptor that named no path. Only what the filtered events contain appears: with no socket events there is no socket source. The filters, the monthly per-view quota, the suppression bucket and the impact-tag predicate mean exactly what they mean on the events page. Add any of source, file and sink as query parameters to also receive focus.events, the newest 200 matching events as list rows in the same 17-element shape as /api/get_all_events_with_count/, with focus.truncated set when there were more; the aggregate is never narrowed by them. A present but empty file selects the descriptor with no path. Add only=focus with a focus to receive just {"focus": ...} when you already hold the graph; a focus request is answered from the map most recently built for the same body, and its events are read fresh, so one that no longer matches the filter is left out. The map covers every event the filter selects, so truncated is false. Any view other than python is a 400.

This is a **read**: a read-only API key may call it.

## Query parameters

- `source` string
- `file` string
- `sink` string
- `only` string

## Request body

- EventQuery: The events filter. Every field is optional, and each matches a control on the events page.
  - `cursor` string: Opaque pagination cursor from a prior next_cursor.
  - `sort` string: List order: newest (the default) or severity (critical first, then high, medium, low and info, newest first within each; events with no recognised severity last). Both orders list the same events. A cursor only continues the order that produced it: a cursor from the other order is a 400, so start again without one when changing order. Any other value is a 400.
  - `whitelist_repr` string, regex: Show only events whose sink label (the where field) matches this regex, case-insensitively. Despite the name, it is not matched against the repr. An invalid regex is a 400.
  - `blacklist_repr` string, regex: Hide events whose sink label (the where field) matches this regex, case-insensitively. Despite the name, it is not matched against the repr. An invalid regex is a 400.
  - `from` string: Lower time bound (RFC3339 or YYYY-MM-DD).
  - `to` string: Upper time bound (RFC3339 or YYYY-MM-DD, inclusive of the whole day).
  - `machine` string: Restrict to one machine by display name (exact match).
  - `severity` string[]: Severity levels to include: critical, high, medium, low, info. Unknown values are ignored.
  - `sources` string[]: Taint-source categories to include, matched against the event's origin: socket, file, stdin, env, argv, manual, fuzzer, foreign. Unknown values are ignored.
  - `tags` string[]: Restrict to events carrying any of these impact class labels (e.g. sqli, xss). An unknown label is a 400.
  - `labels` integer[]: Restrict to events carrying any of these triage label ids (your own, from GET /api/event_labels/).
  - `xss_only` boolean: es-chromium only: keep just the events whose sink can end in script execution. Must be sent with view=browser; with any other view it is a 400.
  - `scope` object: The events page's scope bar, as {mode, value, include_empty}: mode is is, ends (suffix) or regex, matched against the event's scope key (see scope on GET /api/event_view_counts/). A scope with no mode or no value is ignored; an unknown mode or an invalid regex is a 400.
  - `advanced` object: The condition builder, as {match, conditions}: match is all (default) or any, and each condition is {field, op, value, negate}. The fields available depend on the view; an unknown field or an invalid value is a 400.
  - `view` string: Agent kind to include: python, browser, go, c, cpp, rust, node, solidity, java, bash, ruby or php. Omitted or empty = every view your account holds, which is what the pre-views clients this field exists for still get. Naming a view your account does not hold is a 403; if no products are enabled at all, even the omitted form is a 403. Any unrecognised value is a 400, never a silent empty page.
  - `bucket` string: Sanitizer visibility bucket: live (the default, unsuppressed rows only), suppressed, or all. This was briefly named view during development; view now always means the agent kind above.

## Response `200`

OK.

- object

## Other responses

- `401`: The API key is missing, wrong, revoked or expired.
- `429`: A rate limit was hit, or the account is locked after wrong passwords. Retry-After gives the seconds to wait.
- `default`: An error. Check the status first; the body carries a short message, as JSON ({"error": "..."}) on most endpoints and as plain text on some. 400: malformed JSON, an invalid regex, an unreadable cursor or date, or an unknown value. 401: the API key is missing, wrong, revoked or expired. 403: a failed CSRF check, a read-only key trying to write, a product or feature not enabled on your account, a wrong password, or a write on an account limited to reading. 404: not found, including things that belong to another account. 409: conflict with the current state. 422: a field is missing or invalid. 429: a rate limit was hit, or the account is locked after wrong passwords. 500: something failed on our side.

---

[API](https://skmtc.dev/eyalsec/apis/eyalsec-api.md) · [All operations](https://skmtc.dev/eyalsec/apis/eyalsec-api/llms.txt) · [OpenAPI document](https://skmtc.dev/eyalsec/apis/eyalsec-api/revisions/dc7520689cf1?raw)
