Use Cases
The API is made for customers that have a need to access and interact with their HackerOne report and program data and be able to automate their workflows. Customers use this to generate dashboards, automatically escalate reports to their internal systems, assign users based on on-call personnel or when an internal ticket is resolved, interact with the reporters, and more. The public API provides a bi-directional channel to consume and interact with report and program data.
We have provided a Ruby code example below to show how easy it is to use. The code example fetches new and triaged reports, sorted by the last time someone from your program touched it. This example requires the 3rd party gem HTTParty to be installed:
require 'httparty'
basic_auth = {
username: '<YOUR_API_USERNAME>',
password: '<YOUR_API_TOKEN>',
}
query = {
filter: {
program: ['john_doe_example_company'],
state: ['new', 'triaged'],
},
sort: 'reports.last_program_activity_at',
}
HTTParty.get 'https://api.hackerone.com/v1/reports',
query: query,
basic_auth: basic_auth
Importing known vulnerabilities
The API allows you to import known vulnerabilities to your HackerOne program so that you can have central vulnerability management and detect duplicate vulnerabilities. You can use the create report endpoint to systematically import vulnerabilities that are found outside the HackerOne platform, such as from internal tests or via automated vulnerability scanners.
Below is an example on how to import a known vulnerability:
curl "https://api.hackerone.com/v1/reports" \
-X POST \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d @- <<EOD
{
"data": {
"type": "report",
"attributes": {
"team_handle": "security",
"title": "XSS in login form",
"vulnerability_information": "...",
"impact": "...",
"severity_rating": "medium",
"weakness_id": "1337",
"structured_scope_id": "287",
"source": "detectify"
}
}
}
EOD
Using the source attribute, you can define the original source of the vulnerability. This will be helpful in tracking vulnerabilities from specific sources and in running analytics by source. The source attribute will also be returned in the response of the report object.
Using the reports query endpoint
The Get All Reports endpoint allows you to get multiple reports at once. The filters enable you to insert criteria the report has to match to show up in the list. The default filter to get all reports in one program is filter[program]
. Your request would look like:
curl "https://api.hackerone.com/v1/reports?filter[program][]=example" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
Combining multiple filters
Using this endpoint, you can combine multiple filters if you want to make the query more specific. Here's an example that queries all reports in the triaged
state for the john_doe_example_company
program.
curl "https://api.hackerone.com/v1/reports?filter[program][]=example&filter[state][]=triaged&filter[severity][]=medium" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
Combining multiple filter values
This example demonstrates how to select reports for programs with the example
handle and with triaged
or retesting
state.
curl "https://api.hackerone.com/v1/reports?filter[program][]=example&filter[state][]=triaged&filter[state][]=retesting" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
Filtering reports by custom fields
This example demonstrates how to select reports for programs with the example
handle and with custom field values value1
or value2
.
curl "https://api.hackerone.com/v1/reports?filter[program][]=example&filter[custom_fields][][value__eq]=value1&filter[custom_fields][][value__eq]=value2" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
Awarding bounties
The API has 2 different methods for awarding bounties: one for vulnerabilities reported via HackerOne and one for vulnerabilities reported outside of the HackerOne platform. For vulnerabilities reported via HackerOne, you can use the bounty award endpoint:
curl "https://api.hackerone.com/v1/reports/172932/bounties" \
-X POST \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d @- <<EOD
{
"data": {
"message": "Thanks for the great report. Here's your bounty!",
"amount": "500",
"bonus_amount": "250"
}
}
EOD
External bounties
To award a bounty to someone who found a vulnerability outside the HackerOne platform, use the program bounty endpoint. In the example below, there's no report of the vulnerability in the HackerOne system.
curl "https://api.hackerone.com/v1/programs/11000/bounties" \
-X POST \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d @- <<EOD
{
"data": {
"type": "bounty",
"attributes": {
"amount": 100,
"reference": "JIRA1239",
"title": "Reflected XSS on marketing.example.com",
"recipient": "hacker@hackerone.com",
"currency": "USD",
"severity_rating": "high"
}
}
}
EOD
Program management
This section will dive deeper into querying your program information using the API. All endpoints in this section require your program ID. To find your program ID, you can use the following query:
curl "https://api.hackerone.com/v1/me/programs" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
This endpoint returns all programs and their IDs this API token can access.
Finding team members and groups
You can use the read program endpoint to get basic information about your program and its members. The endpoint will return team members and groups associated with the program which can be used to easily see all members of a certain user group.
In the example below, we use the program 11000
which is the ID of our example program.
curl "https://api.hackerone.com/v1/programs/11000" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
Finding allowed reporters and their activities
You can use the get allowed reporters endpoint to get basic information about the allowed reporters of your private program.
curl "https://api.hackerone.com/v1/programs/11000/allowed_reporters" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
To see activities of specific allowed reporter of your private program, you can use the get allowed reporter's activities endpoint
Note that, the activity types you can see are "activity-program-hacker-joined", "activity-program-hacker-left" and "activity-invitation-received"
curl "https://api.hackerone.com/v1/programs/11000/allowed_reporters/1337/activities" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
Fetching the balance
Most programs have a deposit at HackerOne that can be used for bounty payments.
A program that’s using a credit card, won’t have a balance as bounties are directly charged on the credit card. See our documentation for more information about our different payment methods.
curl "https://api.hackerone.com/v1/programs/11000/billing/balance" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
The balance returned is the total balance available in the program. Both the bounty and bounty fee (if applicable) will be paid from this balance.
Fetching billing transactions
All financial transactions made in your HackerOne program are accessible via the transactions endpoint. This endpoint returns a transaction for each change to your balance. This can be a bounty payment, deposit, move of funds, etc.
curl "https://api.hackerone.com/v1/programs/11000/billing/transactions?month=9&year=2019" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
Billing transactions are only available for programs that are in private or public mode. If the program is still in the sandboxed mode, this endpoint will return a 403
response.
Checking if a hacker is participating in your program
Programs that are in private mode can only be accessed by hackers that are invited to the program. To confirm if a hacker is invited and has access, you can query the hacker by using the show user endpoint. In the example below, we’re querying the user fransrosen
:
curl "https://api.hackerone.com/v1/users/fransrosen" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
The API will respond with some basic user information and a list of private programs (participating_programs
) the user has access to. Note that you won’t be able to see private programs you can’t access yourself.
Managing policy
Some companies have their policy page stored in a central git repository for better change management. With the policy endpoint, you can easily keep your policy page in HackerOne up to date based on the changes you’re making externally.
curl "https://api.hackerone.com/v1/programs/11000/policy" \
-X PUT \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d @- <<EOD
{
"data": {
"type": "program-policy",
"attributes": {
"policy": "..."
}
}
}
EOD
Changing the policy text will automatically notify hackers that are subscribed to the program about the policy change.
Adding attachments to the policy
If you have any files that are relevant for hackers, for example an APK file with a special version of your app, you can easily upload these to the policy page using the policy attachments endpoint. This endpoint enables you to upload any file to the policy and use the policy endpoint to include it in the policy.
curl "https://api.hackerone.com/v1/programs/3774/policy_attachments" \
-X POST \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-F "file=@/tmp/example.png"
EOD
The API will respond with an ID that can be included as {ID}
in the policy of the program using the policy endpoint.
Assets management
All asset endpoints require your organization's {ID}
. You can use the below endpoint to get that.
Get your organization ID
curl "https://api.hackerone.com/v1/me/organizations" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
Importing existing assets
The API allows you to import assets into the HackerOne platform and detect duplicates. Below is an example of how to import assets:
curl "https://api.hackerone.com/v1/organizations/10/asset_imports" \
-X POST \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Content-Type: multipart/form-data' \
-H 'Accept: application/json' \
-d @- <<EOD
{
"file": "string"
}
EOD
CSV file
The endpoint accepts a CSV file. Supported CSV format consists of the following columns:
- identifier
- Must be a valid identifier for the selected asset type.
- asset_type
- One of:
Domain
,Url
,Cidr
,Hardware
,SourceCode
,IosAppStore
,IosTestflight
,IosIpa
,AndroidPlayStore
,AndroidApk
,WindowsMicrosoftStore
,Executable
,OtherAsset
- Note: When choosing between
Domain
andUrl
, we recommend going withDomain
.Domain
type assets are fine-grained enough for most purposes,Url
type assets should only be used when differentUrl
s on the same Domain are representing significantly different infrastructure.
- One of:
- technologies
- confidentiality_requirement
- One of
none
,low
,high
- One of
- integrity_requirement
- One of
none
,low
,high
- One of
- availability_requirement
- One of
none
,low
,high
- One of
- description
- reference
Column headers are required.
File example:
identifier;asset_type;technologies;confidentiality_requirement;integrity_requirement;availability_requirement;description;reference
hackerone.com;Domain;technology1,technology2,technology3;high;medium;low;"Asset1 description";ref1
192.168.1.1/32;Cidr;technology4,technology5,technology6;medium;low;high;"Asset2 description";ref2
com.hackerone.example;IosAppStore;technology1,technology2,technology3;low;high;medium;"Asset3 description";ref3
com.hackerone.example;AndroidPlayStore;technology7,technology8,technology9;high;low;medium;"Asset4 description";ref4
This request will return an asset import object. Processing of an asset import happens asynchronously, you can check the status by retrieving the assets import using the asset import ID returned.
Attaching screenshots to an asset
You can upload screenshots to attach to an asset using this endpoint.
curl "https://api.hackerone.com/v1/organizations/10/asset_screenshots" \
-X POST \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-d @- <<EOD
{
"file": "paprika.png",
"asset_id": 12
}
EOD
Organization management
Get your organization ID
All organization management endpoints require your organization's {ID}
. You can use the below endpoint to get that.
curl "https://api.hackerone.com/v1/me/organizations" \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>"
Add a member to your organization
An new organization member can be invited to an organization with {ID}
using the endpoint to
create an invitation and the invitee email.
curl "https://api.hackerone.com/v1/organizations/{ID}/invitations" \
-X POST \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d @- <<EOD
{
"data": {
"type": "invitation-organization-member",
"attributes": {
"email_address": "example@hackerone.com",
"organization_member_group_ids": [],
"organization_admin": true,
"notify": true
}
}
}
EOD
Although the same endpoint it is possible to add the invitee to different groups using the IDs of these groups. Use the following endpoint to view all invitations that are still open
Once you accept the invitation, the member will be added to the specified organization and groups.
The invitee email must respect the eligibility settings of the organization and any groups it will be added to.
Use the following endpoint to retrieve your groups and their IDs
List pending invitations
You can verify if an invitation to become a member of an organization is still open through the endpoint to get all open invitations
curl "https://api.hackerone.com/v1/organizations/{ID}/pending_invitations" \
-X GET \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Accept: application/json'
Use the following endpoint to retrieve your user from their id
curl "https://api.hackerone.com/v1/user_by_id/{USER_ID}" \
-X GET \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Accept: application/json'
Get all the organization members and their groups access
You can retrieve all members, their groups and their access through the endpoint to list all organization members
curl "https://api.hackerone.com/v1/organizations/{ID}/members" \
-X GET \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Accept: application/json'
Get all the organization groups
You can retrieve all groups through the endpoint to list all organization groups
curl "https://api.hackerone.com/v1/organizations/{ID}/groups" \
-X GET \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Accept: application/json'
Remove a user from an organization
You can remove a user as a member of an organization through the endpoint to remove an organization member
curl "https://api.hackerone.com/v1/organizations/{ID}/members/{ID2}" \
-X DELETE \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Accept: application/json'
Use the following endpoint to retrieve your members and their IDs
Update an organization member and their membership groups
You can modify an organization member through the endpoint to update organization member
curl "https://api.hackerone.com/v1/organizations/{ID}/members/{ID2}" \
-X PUT \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d @- <<EOD
{
"data": {
"type": "organization-member",
"attributes": {
"organization_admin": true
},
"relationships": {
"organization_member_groups": {
"data": [
{
"id": 1,
"type": "organization-member-group"
}
]
}
}
}
}
EOD
Use the following endpoint to retrieve your groups and their IDs
Create an organization member group with members, programs and permissions
You can create a new organization member group through the endpoint to update organization member group
curl "https://api.hackerone.com/v1/organizations/{organization_id}/groups" \
-X POST \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d @- <<EOD
{
"data": {
"type": "organization-member-group",
"attributes": {
"name": "Group name",
"permissions": [
"read only"
],
"eligibility_setting_id": 1
},
"relationships": {
"organization_members": {
"data": [
{
"id": 2,
"type": "organization-member"
}
]
},
"programs": {
"data": [
{
"id": 3,
"type": "program"
}
]
}
}
}
}
EOD
Use the following endpoint to retrieve your members and their IDs
Use the following endpoint to retrieve your eligibility settings and their IDs
Update an organization member group and their members, programs and permissions
You can modify an organization member group through the endpoint to update organization member group
curl "https://api.hackerone.com/v1/organizations/{organization_id}/groups/{id}" \
-X PUT \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d @- <<EOD
{
"data": {
"type": "organization-member-group",
"attributes": {
"name": "Test",
"eligibility_setting_id": 1,
"permissions": [
"report_analyst"
]
},
"relationships": {
"organization_members": {
"data": [
{
"id": 2,
"type": "organization-member"
}
]
},
"programs": {
"data": [
{
"id": 3,
"type": "program"
}
]
}
}
}
}
EOD
Use the following endpoint to retrieve your groups and their IDs
Use the following endpoint to retrieve your eligibility settings and their IDs
Get all organization programs
You can retrieve all programs through the endpoint to list all organization programs
curl "https://api.hackerone.com/v1/organizations/{ID}/programs" \
-X GET \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Accept: application/json'
Get all eligibility settings
You can retrieve all eligibility settings through the endpoint to list all eligibility settings
curl "https://api.hackerone.com/v1/organizations/{ID}/eligibility_settings" \
-X GET \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Accept: application/json'
Automatic inbox assignment
Through a combination of webhooks and api calls, reports can automatically be routed to specific custom inboxes based on any report attribute.
Permissions
In order to be able to assign reports submitted to a program, to a specific custom inbox, the API token needs to have at least the following permissions:
- Report permission on the program
- Read only permission on the custom inbox
Now we’ll need some pieces of information, namely the organization ID, and ID’s of the custom inboxes we’ll be using.
Finding our Organization ID
We can use the get your organizations API call to find our Organization ID:
curl "https://api.hackerone.com/v1/me/organizations" \
-X GET \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Accept: application/json'
Which returns something like:
{
"data": [
{
"id": "13", # <-- This is the organization ID we are looking for.
"type": "organization",
"attributes": {
"handle": "example",
"created_at": "2013-01-01T00:00:00.000Z",
"updated_at": "2023-03-07T09:19:46.377Z"
}
}
]
}
Finding our Custom Inboxes
Now we need to find the ID’s of the custom inboxes we want to assign reports to using the get all inboxes
curl "https://api.hackerone.com/v1/organizations/13/inboxes" \
-X GET \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Accept: application/json'
Which will return something like:
{
"data": [
{
"id": "13",
"type": "inbox",
"attributes": {
"name": "Example program inbox",
"type": "default" # <-- Note that reports cannot be assigned or unassigned from default inboxes
}
},
{
"id": "65", # <-- This is an ID we’re interested in
"type": "inbox",
"attributes": {
"name": "Example custom inbox for asset A",
"type": "custom"
}
},
{
"id": "67", # <-- This is an ID we’re interested in
"type": "inbox",
"attributes": {
"name": "Example custom inbox for asset B",
"type": "custom"
}
}
]
}
Note: Only inboxes which have "type": "custom" in their attributes can have reports assigned to them.
If you are not seeing the custom inbox you are looking for in this list, ensure that the api token has at least Read Only permission on that custom inbox.
Determining inbox mapping.
Now we need to create some mapping of a report attribute to a Custom Inbox ID. In this example, we’ll use the asset identifier of a structured scope. This mapping will be stored in your own API service, and will be referred to when a new report comes in.
[
{
"example.com": "65",
"example.co.uk": "65",
"example.nl": "67"
}
]
Triggering the service when a report comes in
In order for the service to know when a report comes in, we need to set up a webhook on hackerone.com. Set this webhook to trigger on the "Report created" event.
Retrieving the relevant information
when that webhook is triggered, the body will contain a payload that includes the report ID. We can then fetch the report through the API, and find the structured_scope information we’re looking for.
curl "https://api.hackerone.com/v1/reports/292" \
-X GET \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Accept: application/json'
Which returns (abbreviated for legibility)
"data": {
"id": "292",
"type": "report",
# [.. abbrev ..]
"relationships": {
# [.. abbrev ..]
"structured_scope": {
"data": {
"id": "4",
"type": "structured-scope",
"attributes": {
"asset_type": "URL",
"asset_identifier": "example.nl", # <-- The asset identifier
"eligible_for_bounty": true,
# [.. abbrev ..]
}
}
},
# [.. abbrev ..]
}
}
If you get any 4xx error on this request, ensure the API token has "Report" permission on the program inbox the report is in.
Updating the custom inboxes
Looking at our mapping, we see that "example.nl" should be routed to inbox "67". In order to achieve this, we can use the update inboxes endpoint:
curl "https://api.hackerone.com/v1/reports/292/inboxes" \
-X POST \
-u "<YOUR_API_USERNAME>:<YOUR_API_TOKEN>" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d @- <<EOD
{
"data": {
"organization_inbox_ids": ["67"]
}
}
EOD
The report will now show up in "Example custom inbox for asset B", as well as the default inbox it was submitted to.
If you get any 4xx error on this request, ensure that the API token has at least "Report" permission on the program inbox the report is in.