TheHive 4.0.4 and TheHive4py 1.8.1: alerts got more APIs

Dear community, the new year has brought us another opportunity to build new features in your favorite Security Incident Response Platform, TheHive. We wish you a cheerful new year ahead and we thank you for being beside us all these years.

Last week, we released TheHive 4.0.4 and TheHive4py 1.8.1, and here is the official announcement including the details of the new features.

These releases focused on adding more capabilities to play with alert observables and give more flexibility when building alert feeders.

Please find the change logs for more details:

What’s new in TheHive

New Alert observable APIs

The major change in TheHive 4.0.4 is related to alert management. In TheHive 3, alert observables were included in the alert as an array of observable objects, and not as independent objects with links to the alert itself. This data model made alert observables CRUD operations, a bit challenging.

TheHive 4 has a better design for this, and alert observables have their own existence, and can be added/updated and deleted independently from the alert object.

This new design allows adding dedicated API endpoints to:

  • Add an observable to an existing alert;
  • Update the data of an existing alert observable;
  • Delete an observable from an alert.

Those APIs are not used by the user interface for now.

New Alert properties

This release introduced a new property called `importDate`. It represents the date at which an alert has been merged into a new/existing case. This property is then used to:

  • Allow filtering the alert list, for example: “List the alerts merged today”
  • Display the duration between the alert creation and its merge into a case.
Alert list showcasing alert importDate

This new property is of course available on the dashboard creation UI as a date field, among others:

  • imported: true if the alert has been merged
  • `handlingDurationInSeconds`: number of seconds before importing an alert
  • `handlingDurationInMinutes`: number of minutes before importing an alert
  • `handlingDurationInHours`: number of hours before importing an alert
  • `handlingDurationInDays`: number of days before importing an alert

To showcase the mentioned new properties, here are some screenshots:

importDate field used on a line chart as date field for x-axis
Simple line chart using the imported filter
Dashboard including two charts using the newly introduced alert fields

What’s new in TheHive4py

The 1.8.1 release of TheHive4py mainly focuses on adding support to the new alert APIs introduced by TheHive 4.0.4. It comes with 3 new functions:

  • `create_alert_artifact` to allow developers adding a new artifact to an existing alert
from thehive4py.api import TheHiveApi
from thehive4py.models import Tlp



# Instanciate a new domain artifact
artifact = AlertArtifact(dataType='domain', data='malicious-domain.tld', ignoreSimilarity=True, ioc=True)
api.create_alert_artifact(ALERT_ID, artifact)

# Instanciate a new file artifact
artifact = AlertArtifact(
api.create_alert_artifact(alert_id, artifact)
  • `update-alert-artifact` to allow updating the data of an existing alert artifact:
from thehive4py.api import TheHiveApi
from thehive4py.models import Tlp



# Create a new domain artifact
artifact = AlertArtifact(dataType='domain', data='malicious-domain.tld', ignoreSimilarity=True, ioc=True)
response = api.create_alert_artifact(ALERT_ID, artifact)

# Update its tlp, sighted and ignoreSimilarity flags
artifact_data = response.json()[0]
artifact_data['tlp'] = Tlp.RED.value
artifact_data['sighted'] = True
artifact_data['ignoreSimilarity'] = False

new_artifact = AlertArtifact(json=artifact_data)
api.update_alert_artifact(artifact_data['id'], new_artifact, fields=['tlp', 'ioc', 'ignoreSimilarity'])
  • `delete_alert_artifact` to allow removing an existing artifact from an existing alert
from thehive4py.api import TheHiveApi



# Delete alert artifact

Note that these new three methods are only available when using TheHive4py with TheHive 4.0.4+

You can find more details on the official documentation of TheHive4py.


To update your existing package to version 1.8.1:

$ sudo pip install thehive4py --upgrade

How to report issues

Please open an issue on GitHub with the dedicated template for TheHive 4 or the dedicated form for TheHive4py. We will monitor them closely and respond accordingly. 

Running Into Trouble?

Shall you encounter any difficulty, please join our user forum, contact us on Discord, or send us an email at We will be more than happy to help!

TheHive4py 1.8.0 is hot off the press

TheHive4py 1.8.0 is finally released. During the last 5 months, the team was busy working on TheHive and Cortex but today, it’s time to unveil the biggest milestone of TheHive’s official python API client.

TheHive4py official documentation website

1.8.0 contains 31 Github issues including 17 contributions for which, we would like to thank all the community members who helped shaping the release.

TheHive4py is getting a bit hard to maintain because of the backward compatibility constraints introduced by TheHive 3 and 4 versions. TheHive 4 also introduces new features that are not available in TheHive 3, and this makes it challenging to serve both versions with the same code base.

TheHive 4 has also its dedicated and optimised APIs (read APIs v1), and those are not used by TheHive4py, which is still relying on APIs v0 of TheHive 4.


What’s new?

1.8.0 release introduced a significant number of new methods and changes:

  • attachment download support for files (by id), observables and task log attachments
  • alert merge into case
  • alert delete
  • case task delete
  • case task log search
  • task log search
  • support to alert similarity in fetch
  • case observable search method
  • case observable fetch method
  • case observable delete method
  • support to in memory files when calling APIs evolving attachments
  • MISP export
  • support to PAP in alerts
  • add Tlp, Pap, Severity, CaseStatus, TaskStatus enumerations

in addition to some TheHive 4 related features:

  • Add a version parameter to TheHiveApi class’s constructor
  • Add support to ignoreSimilarity attribute
  • Add support to alert.externalLink attribute

Please read the full release notes for more details.

Below, we will highlight the major features other than the self explanatory newly added methods.

New version parameter

This change is important and required for developers using TheHive4py to play with a TheHive 4 instance. the `version` parameter has been introduced to allow fine tune access to features available on TheHive 4 and not in TheHive 3, like for `alert.extrnalLink` field.

The version is set by default to Version.THEHIVE_3.value, which means version 3.

from thehive4py.models import Version

# Init an API client for TheHive 4
api = TheHiveApi(THEHIVE_URL, API_KEY, version=Version.THEHIVE_4.value)

Add support to ignoreSimilarity field

This capability has been introduced by TheHive 4.0.1 release. It allows setting an `ignoreSimilarity` flag at the case and alert observable level. When set to True it tells TheHive to ignore the observable from any similarity computing.

So, if you need to create an alert with an observable you would like to skip when running the similarity algorithm, then, you need to set ignoreSimilarity to True

Here is an example that creates and alert with an observable to be ignored for similarity:

import uuid
from thehive4py.api import TheHiveApi
from thehive4py.models import Tlp, Pap, Alert, AlertArtifact

sourceRef = str(uuid.uuid4())[0:6]

# Prepare the Alert object
alert = Alert(title='Sample alert - ID {}'.format(sourceRef), 
  description='Sample alert for the blog post',

# Init an API client instance
api = TheHiveApi(THEHIVE_URL, THEHIVE_API_KEY, version=4)

# Create the alert
response = api.create_alert(alert)

Note that the same option is available for Case observables during creation and update:

# Set an observable as ignorable

   {"ignoreSimilarity": True}, 

Support in-memory files

Old versions of TheHiv4py required existing files when dealing with attachments. For example, to create a file case observable, the corresponding file has to be already stored on the file system before calling the `create_case_observable` method.

This release allows using files from memory and not relying on file paths. So you use, for example, an API to download a file and you want to store that file as observable, you can use the new feature of TheHive4py, as below:

from thehive4py.models import Tlp, Pap, Alert, CaseObservable

# Say you have a method to get a screenshot
file = get_screenshot()

# Prepare the observable
observable = CaseObservable(
    data=(file, 'screenshot-{}.png'.format(int(time.time())*1000)),

# Create the observable
response = api.create_case_observable(case_id, observable)

# Close the file object

Note: closing the file object is still required. We will handle closing the files during the upcoming releases.

Attachment download features

The new methods introduced by 1.8.0 release and related to attachment download, light some interesting TheHive APIs up.

Did you know TheHive has APIs to download existing file from the datastore? Do you know how does TheHive store files?

Well, when a file is uploaded to TheHive as case observable, alert observable or case log attachments, the file is stored in the DataStore and is given an ID that can be used in two APIs:

  • `/api/datastore/{attachment_id}`: downloads the file content
  • `/api/datastorezip/{attachment_id}`: downloads the file content as zip password protected file, and the password is the one defined in application.conf (defaults to `malware`)

In this release, we introduced methods to make these APIs available on TheHive4py.

Download an attachment by its ID

This method is useful if you know the attachment ID (could be an alert file observable for exemple, in TheHive 4)

# Download an attachment by a known id
response = api.download_attachment(

# Save the attachment to disk
f = open('./{}'.format('screenshot.png'), 'wb')

Download an attachment of a task log

This method allows downloading the attachment of a given task log object, identified by its ID

response = api.download_task_log_attachment(log_id, archive=False)

f = open('./{}'.format('screenshot.png'), 'wb')

If the task log doesn’t have an attachment, this methods throws an exception.

Download a file attachment of a file observable

This methods allows downloading a file observable, and forces protecting it as password protected zip archive

response = api.download_observable_attachment(observable_id)

f = open('./{}'.format(''), 'wb')

If the observable is not a file, this methods throws an exception.


As you might know, with the 1.7.0 release we released a documentation website for TheHive4py where all the methods are documented. Donc hesitate to refer to it for more details:


To update your existing package to version 1.8.0:

$ sudo pip install thehive4py --upgrade

Got a question?

If you encounter any difficulty, please join our  user forum, contact us on Discord, or send us an email at As usual, we’ll be more than happy to help!

TheHive4py got a second wind, version 1.7.0 released

“TheHive4py”, this sounds like a word you didn’t hear about during the last 12 months. Well, our focus on this library was put on hold. We will tell you the reason, but much better, we will solve the problem.

A brief review

TheHive4py was quickly initiated after the first releases of TheHive to help developers interact with TheHive APIs using python. We started creating methods and functions for main functionalities and to be honest, it was a sort of a quick-and-dirty solution.

TheHive4py has some limitation:

  • The API client is a flat class with dozens of methods
  • The API clients’ methods return the native `requests.Reponse` class instead of a structured data
  • Exception handling could be improved
  • Code could be made more reusable

As developers, we are aware of these limitations and are eager to provide a better library, and that’s what we started making with TheHive4py rewrite. We wanted to provide you with a library you can use this way:

# Fetch cases
open_cases = api.cases.find_all({'status': 'Open'}, range='0-5')
log('Open cases', list(map(lambda i: i.json(), open_cases)))

# Fetch a case by `id` or `number` (caseId)
sample_case = open_cases[0]
log('case details by id', api.cases.get_by_id(
log('case details by number', api.cases.get_by_number(sample_case.caseId).json())

# Fetch alerts
new_alerts = api.alerts.find_all({'status': 'New'}, range='0-2')
log('New alerts', list(map(lambda i: i.json(), new_alerts)))

# Fetch observables
domain_observables = api.observables.find_all({'dataType': 'domain'}, range='0-2')
log('New alerts', list(map(lambda i: i.json(), domain_observables)))

# Fetch tasks
waiting_tasks = api.tasks.find_all({'status': 'Waiting'}, range='0-2')
log('Waiting tasks', list(map(lambda i: i.json(), waiting_tasks)))

waiting_tasks = api.tasks.get_waiting(range='0-2')
log('Waiting tasks', list(map(lambda i: i.json(), waiting_tasks)))

jdoe_tasks = api.tasks.get_by_user('jdoe', {}, range='0-3')
log('Tasks of jdoe', list(map(lambda i: i.json(), jdoe_tasks)))

case_tasks = api.tasks.of_case(, query={'status': 'Waiting'})
log('Case tasks', list(map(lambda i: i.json(), case_tasks)))

The library’s rewrite was supposed to produce a 2.0.0 version of TheHive4py but we had a major issue: backward compatibility.

Well, in theory, backward compatibility can be handled through a clear communication to:

  • tell the users how to make sure to update their dependencies to TheHive4py < 2.0.0
  • provide a migration plan
  • maintain both versions during a certain time
  • maintain documentation for old and new versions

To be honest, this was hard to achieve, because of the famous lack of time, but things a going to change.

What’s the plan?

We didn’t want to make a plan without asking the community about how they interact with TheHive APIs. So we did two twitter polls that ended up with the following results:

Twitter poll about TheHive API usage methods

The second poll asked our users about pros and cons of TheHive4py:

Twitter poll about TheHive4py pros and cons

The poll results are clear: we need to put more efforts on TheHive4py.

Here we go, firstly, let’s release version 1.7.0

TheHive4py 1.7.0 milestone has been initiated almost one year ago, and we are happy to announce its availability today.

What’s new about it?

The most important change is allowing TheHive4py to interact with TheHive 4 in addition to introducing some missing features, and bug fixes. Here is a short listing of main changes:

Add support to multi tenancy

Allow a developer to specify the organisation against which an API call is done:

api = TheHiveApi('http://my_thehive:9000', 'my_api_key', organisation='cert')

Add custom field support for new types:

TheHive 4 introduces custom fields of type integer and float, this feature allows specifying custom fields with types supported by TheHive 4. These types are not supported by TheHive 3.

   .add_integer('number_hits', 10)
   .add_float('cvss', 5.6)

The code snippet above produces the following content:

  "number_hits": {
    "order": 0,
    "integer": 100
  "cvss": {
    "order": 1,
    "integer": 5.6

Add support to like and wildcard query operators

TheHive query DSL supports like and wildcard operators, but TheHive4py didn’t had an option to use those operators. In this version the following query methods have been added:

  • Like (field, value): Field’s value must contain value, that must contain `*` in the beginning or at the end
  • StratsWith (field, value): Field’s value must start with value
  • EndsWith (field, value): Field’s value must end with value
  • ContainsString (field, value): Field’s value must contain value
from thehive4py.query import Eq, Like, And, StartsWith

# find cases where title contains 'Dridex'
api.find_cases(query=Like('title', 'Dridex*'))

# find alerts where status is 'New' and title starts with 'Emotet'
api.find_alert(query=And(Eq('status', 'New'), StartsWith('title', 'Emotet')))

Add ioc and sighted attributes to case and alert artifacts

This allows specifying these attributes during Alert or Case observables creation

Add update_case_observable method

Can be used to patch an existing observable, by setting a tag or marking as IOC.

Add PAP to Case and CaseTemplate models

PAP flag has been added in TheHive recently and TheHive4py was not able to set the PAP value of a Case or CaseTemplate

Add custom fields creation method

Added a `create_custom_field` method that check custom field name uniqueness before creating it.

Note: This method is for now, compatible with TheHive 3 only because it relies on the DBList API that is no longer available on TheHive 4.

Add case template creation method

Added a `create_case_template` method allowing developers to create new Case Templates.

The full change log is available at the release page

What about documentation

Once again we are glad to announce the initial version of a documentation website, dedicated to TheHive4py, including documentation of all the features the library provides, and code samples of the most useful features.

We aim to maintain and improve this documentation over time, so please, don’t hesitate to either contribute or ask for more content.

Screenshot of the documentation website

TheHive4py 2.0

We will put the rewrite of TheHive4py on hold for now and will communicate about it again when we are ready. In the meantime, we will continue maintaining TheHive4py 1.x.

Update: TheHive4py 1.7.1 Patch

During the release 1.7.0, we have noticed that the build process and deployment went wrong, so we have created a 1.7.0.post1 release.

The community also raised a regression that has been fixed in 1.7.1 release. You can read the change log for more details.


To update your existing package to version 1.7.0:

$ sudo pip install thehive4py --upgrade

Got a question?

If you encounter any difficulty, please join our  user forum, contact us on Gitter, or send us an email at As usual, we’ll be more than happy to help!

Unveiling Synapse

When we’re not busy cooking new features, we go back to the trenches and face incidents like many of our fellow analysts who read our publications and use our tools. To do so, we swap our chef toques for firefighter helmets, not only because such shiny headwear is cool, but mainly because incident response (IR) is, at its very heart, firefighting (minus all the dangerous stuff).

If you think about it, when handling incidents you can see everything from cats in trees (spam) to major fire (APT). Thankfully, there are more cats to bring down than fire to extinguish. That being said, a big herd of cats could be a serious threat to your organization, to your mental health or both.

We tend to forget that incident handlers are humans, not robots. Unlike our metal cyberfriends, we need diversity. We can’t risk insanity like Charlie Chaplin in Modern Times if we can avoid it. Unfortunately IR can be highly repetitive, especially if you only have cats to deal with.

Some could say ‘Nah, this is minor, nothing critical here’ but at some point, an analyst brainwashed by the same tasks again and again will be led to fault. In the worst case scenario, one could see an alert and immediately categorize it as false positive without any further consideration. Because ‘this alert is always a false positive’, until the day it is not…

Automation, a Solution?

Intuitively, we look in the direction of automation in order to minimize what we call ‘zombie’ tasks: highly repetitive and brainless tasks that need to be done. We believe that doing so will allow incident handlers to focus on the analysis and not on the tedious side of IR. Ultimately, we hope it will keep analysts stimulated and in a state of alert. Also, it should reduce time and effort spent on the low-hanging fruits.

One of the most dreary tasks in our opinion is to record the context around an incident.
What is the problem? When did it happen? What’s the origin? Who are the victims? How many are there? Answers to these questions let you have an overview of what is happening and are valuable to correlate incidents. So it is worth taking some minutes to add this information to your case. Sadly, most of the time it will look like a succession of ‘Ctrl+C; Alt+Tab; Ctrl+V’ from your incident source to TheHive. Exactly the kind of tasks we want to forego.


Having identified the threat that apathetic analysts pose, the root cause (highly repetitive tasks) and a solution (automate the recording of incident context), the question of the implementation has been raised.

The first challenge to solve is the number of incident sources. Almost everything can trigger an incident: a firewall, an IDS, antivirus, SIEM, users, etc… So the application must be designed to accept several sources and must permit to easily integrate new ones. And instead of having to configure multiple alert feeders to supply alerts to TheHive, we would have only one. To some extent, it can be assimilated to a meta feeder.

And if the application works as intended, we still have a second challenge. Let’s say you, dear reader, and ourselves use the galaxy renowned Stargazer IDS. Maybe you’d like to include the full packet capture in the case but we wouldn’t. Using the same product doesn’t mean using it the same way. So we have a variety of sources and for each source, we have a variety of configurations and workflows. Hence any app we design needs to accept multiple configurations and workflows for any given source.

Finally: the third challenge. We want to make the most out of TheHive. Creating cases, creating alerts, assigning cases, adding logs, adding observables … all those actions are not an option.


After several trials and failures, we came up with Synapse. Basically it is a Python 3 app which sits between TheHive and your incident sources:

Screen Shot 2018-07-18 at 09.54.28.png
Synapse Overview

To solve the first and third challenge, we rely on connectors. A connector is a Python object dedicated to interact with a security device. In the picture above, you can see the Exchange Connector and TheHive Connector. To extend the number of sources, you just have to develop the connector that corresponds to your device.

Regarding the second challenge, we rely on workflows. Workflows are python scripts who use connectors to automate repetitive tasks when tracking a case. Not happy with the current workflow? Develop your own using the connectors.

At this point, you probably wonder why there’s an API in the picture above. Well, the API is the link between the user and the workflows. By hitting a specific endpoint of the Synapse’s API, the corresponding workflow will be launched. That way the user can choose what to launch, especially if they are only interested in a particular workflow. Moreover, using an API allows us to listen to TheHive’s real-time stream and initiate some actions like closing a QRadar offense when the related case is solved.

At the moment, Synapse includes the Exchange connector and the associated Ews2Case workflow. The workflow features:

  • Case creation from emails
  • Case assignment
  • Adding email bodies to task logs
  • Adding email replies to the case
  • Adding email attachments as observables

And of course, everything is done to minimize the number of clicks! Check the workflow documentation to understand how it works under the hood.

We’re still working on the QRadar connector and the associated workflows but if you can’t wait, have a look at the work done by the community like pierrebarlet’s script.

Check it Out

As usual, Synapse is an open source and free software released under the AGPL (Affero General Public License).

Synapse has its own repository. Start with the user guide and read about the workflow you want to use as you’ll need to configure it.


Shall you encounter any difficulty, please join our user forum, contact us on Gitter, or send us an email at We will be more than happy to help!

TheHive4py 1.4.0 Released

Version 1.4.0 of the Python API client for TheHive is now available. It is compatible with the freshly released Cerana (TheHive 3.0.0).

We’d like to thank Nick Pratley, a frequent contributor, Bill Murrin, Alexander Gödeke and “srilumpa” for their code additions and documentation.

To update your existing package:

$ sudo pip install thehive4py --upgrade

If you are just getting started with TheHive4py, you can forgo the --upgrade at the end of the command above.

New Features

  • #5: Add a method to update a case, contributed by Nick Pratley
  • #34: Add a get_task_logs method in order to obtain all the task logs associated with a given taskId. Contributed by Bill Murrin
  • #37: A new, very cool case helper class by Nick Pratley
  • #39: Add support for custom fields to the case model
  • #40: Ability to run a Cortex analyzer through the API by Alexander Gödeke
  • #45: Simplify case creation when using a template by providing just its name
  • #49: Add a query builder capability to support TheHive’s DSL query syntax

Paris? Are you There?

Shall you encounter any difficulty, please join our  user forum, contact us on Gitter, or send us an email at As usual, we’ll be more than happy to help!

TheHive4py 1.3.0 is Here

Version 1.3.0 of the Python API client for TheHive is now available. It is compatible with the freshly released Mellifera 13. This new release includes the changes outlined below.

To update your existing package:

$ sudo pip install thehive4py --upgrade

If you are just getting started with TheHive4py, you can forgo the --upgrade at the end of the command above.

New Features

  • Add more options to sort, filter and paginate case tasks and observables
  • Add a find_alerts method to allow querying alerts
  • Add support to API Key authentication mechanism

Bug Fixes

  • Added verify parameter to calls

Breaking Changes

  • The `get_case_tasks` method has been made consistent with all the other methods and now returns a `Response` object instead of a JSON dict.

Houston? Are you There?

Shall you encounter any difficulty, please join our  user forum, contact us on Gitter, or send us an email at As usual, we’ll be more than happy to help!

TheHive4py 1.2.2 is Here

It’s a sunny week in Paris, France (not Texas) barring the tropical rain that washed out the city earlier this morning. And when there’s sun in France, there’s happiness and… coding of course (what else?). The French Chefs of TheHive Project seem to be in a good mood (n’est-ce pas Jérôme ?), thanks to the vitamin D extra charge they got for free from the big star up above.

After updating CortexUtils and the analyzers, and releasing Mellifera 12, a new, major version of TheHive, why stop there when you can update TheHive4py as well?

Version 1.2.2 of the Python API client for TheHive is now available. It mainly fixes issues related to missing Python dependencies and adds support for creating alerts containing files for Python 3.

To update your existing package:

$ sudo pip install thehive4py --upgrade

If you are just getting started with TheHive4py, you can forgo the --upgrade at the end of the command above.

Houston? Are you There?

Shall you encounter any difficulty, please join our  user forum, contact us on Gitter, or send us an email at As usual, we’ll be more than happy to help!