This is a general reference to the urls, filters, and operators available via rest https calls in Phantom. This is not exhaustive and you do have to be authenticated to use these. More often than not, you can get the data you need from the phantom UI, but in scripts and custom playbook utilities, this API is probably where you will end up going. It is almost always faster and easier to script up a report than to try to harvest the report data from the UI directly.
/rest/container
/rest/container/<id>
/rest/container/<id>/comments
/rest/container/<id>/attachments
/rest/container/<id>/playbook_runs
/rest/container/<id>/actions
/rest/workbook_task
/rest/workbook_phase
/rest/app
/rest/app_run
/rest/app_run/<id>
/rest/app_run/<id>/log
/rest/artifact
/rest/artifact/<id>
/rest/playbook
/rest/playbook/<id>
/rest/playbook_run
/rest/playbook_run/<id>
/rest/playbook_run/<id>/log
/rest/action_run
/rest/action_run/<id>
/rest/action_run/<id>/app_runs?include_expensive
/rest/container_attachment
/rest/container_attachment/<id>
/rest/container_comment
/rest/container_comment/<id>
/rest/decided_list
/rest/decided_list/<list_name>
/rest/ingestion_status
/rest/app_status
/rest/health
/rest/notification_summary
/rest/system_settings
/rest/container_options
/rest/container_status
/rest/severity
If needed, list are unique data sets and can be formatted in CSV:
/rest/decided_list/<list_name>/formatted_content?_output_format=csv
Pretty Names
For objects that contain IDs of other objects, you can frequently get the pretty name of the ID to return in the object by adding
?pretty
You cannot filter or otherwise interact with the pretty values via url parameters
Expensive Fields
In some cases you can get more detail from a record by using
?include_expensive
but its not frequently useful and it is named expensive because it is.
This can substantially slow down some query operations
To include specific data use _filter
Example:
?_filter_name="test"
• Shows only results that exactly match "test" in the name field
To exclude specific data use _exclude
Example:
?_exclude_name="test"
• Shows only results that do not exactly match "test" in the name field
To access subfields in data use __ between parent and child fields
Example:
?_exclude_cef__username__startswith="john"
• username in this case is a key in the cef dictionary and must be accessed via its parent key
To sort on a field use
?sort=<filed_name>
To specify asceding or descending order for your sort use
?order=asc
or
?order=desc
Default max results returned is 10. To get more or less use
?page_size=
To paginate and parse through pages, use
?page=
The total number of pages is included in the json response as num_pages
To get all results in a single page use
?page_size=0
For all of the below operators, _filter and _exclude are interchageable as needed
Matches null values or not null values based on boolean parameter
Example:
?_filter_name__isnull=True
• True shows null matches
• False shows not null matches
Matches values greater than integer or date parameter
Example:
?_filter_artifact_count__gt=0
?_filter_create_time__gt="2018-01-01T00:00:00.000000Z"
Matches values greater than or equal to integer or date parameter
Example:
?_filter_artifact_count__gte=1
?_filter_create_time__gte="2018-01-01T00:00:00.000000Z"
Matches values less than integer or date parameter
Example:
?_filter_artifact_count__lt=10
?_filter_create_time__lt="2018-01-01T00:00:00.000000Z"
Matches values less than or equal to integer or date parameter
Example:
?_filter_artifact_count__lte=150
?_filter_create_time__lte="2018-01-01T00:00:00.000000Z"
Matches values that start with the string parameter
Example:
?_exclude_name__startswith="Test"
(ignore case) matches values that start with the string parameter
Example:
?_exclude_name__istartswith="Test"
Matches values that contain the string parameter
Example:
?_exclude_name__contains="green"
(ignore case) matches values that contain the string parameter
Example:
?_exclude_name__icontains="green"
Matches values that end with the string parameter
Example:
?_exclude_name__endswith="s$"
(ignore case) matches values that end with the string parameter
Example:
?_exclude_name__iendswith="s$"
Matches values within the integer or date parameters
Example:
?_filter_create_time__range=("2018-06-19T20:10:41.687799Z","2018-06-19T20:10:41.687799Z")
?_filter_id__range=(755320,755323)
Matches values that match a value in the list of values in the parameter
Example:
?_exclude_label__in=("test","scheduled-weekly")
Any labels that exactly match any of the strings in the list will be excluded from the results
Matches string values that match the regex parameter
Example:
?_filter_label__regex=".notable."
Fairly complex regex can be handled here but don't be excessive. Most filters or exclusions can be accomplished without regex.
Exact is essentially useless since a straight = operator gets that job done, but iexact can come in handy occassionally
These can be combined in a url as needed to get the specific results you need
https://phantomserver.company.com/rest/container?sort=id&order=asc&_filter_playbookrun__container__isnull=True&_filter_ingest_app__isnull=False&_filter_artifact_count__gt=0&_filter_create_time__range=("2019-08-01T00:00:00.000000Z","2019-09-01T00:00:00.000000Z")&_exclude_label__in=("test","scheduled-weekly")
You can filter on many endpoints with data from others using some undocumented black magic joiny stuff. There is guess work involved and you can't see any of the data from the other referenced endpoints but they can be used to do some cool stuff.
For instance, this rest url is showing data for action_run, but it is being filtered by associated values in playbook_run. This will give you the action_runs where the associated playbook_run had a "failed" status
/rest/action_run?_filter_playbook_run__status="failed"
Another example is this
/rest/action_run?_filter_playbook__name__icontains="rule"
This will show only actions runs that were part of a playbook that had "rule" in the playbook name. These can be super helpful and can get you results that you would otherwise need multiple rest calls and some data processing to achieve.
One of the most creative and also darkest of magics I have seen with these filters is the this:
/rest/container?_filter_playbookrun__container__isnull=True
This will show containers that have associated playbook_runs with a null container field. This seems like it should show us nothing since a playbook without a container is impossible but it actually shows us the containers that have no associated playbook_runs.
I mentioned that there is guess work involved and hopefully you noticed that in the first example, we filtered with playbook_run and in the second we filtered with playbookrun. These aren't interchangeable. Most endpoints will spit out a helpful list if you put in bad filter fields so if you are struggling, try running this filter for your endpoint:
?_filter_showmethedata=True
Best of luck on the dark side.
You have to be authenticated with headers, tokens, etc to use these APIs outside of phantom, but inside of custom playbook code and utilities, you have other options.
If you use phantom.requests
instead of requests
your API request will be automatically passed to the phantom API using the auth of the user executing the playbook (usually automation). This bypasses a lot of potential challenges exposing API tokens and things like that so definitely use the rest API in playbook code but use phantom.requests and make your life a ton easier