Skip to main content

Setup

Fluid Attacks' platform allows users to make requests to its GraphQL. To get started, it is recommended to get some basic knowledge of this query language.

What is GraphQL?

GraphQL is a query language for APIs, with a single endpoint which is https://app.fluidattacks.com/api where you can perform requests with Queries to fetch data and Mutations to create, delete, and modify the data you need. Having this clear, it is necessary to have basic knowledge of this language; if you are new to GraphQL, we invite you to read more here.

After learning the basics, let’s find out how we can authenticate ourselves and start exploring the GraphQL API.

Authentication

There are two ways you can authenticate and start using the API: from the GraphiQL playground or by HTTP requests in code.

We will now explain the GraphiQL playground authentication, which allows two ways.

Authentication with Fluid Attacks' platform login

Here the authentication is done through Fluid Attacks' platform login, these are the following steps:

  1. Log in to https://app.fluidattacks.com
  2. Open https://app.fluidattacks.com/api

You can write the queries you need, and then click the “play” button to get the answer to your request.

Play Button

Note: This method uses the same session as the web application, which lasts for 40 minutes. After that, you need to log in to https://app.fluidattacks.com again and refresh the https://app.fluidattacks.com/api page. If you want your session to last more than 40 minutes, you can use an API Token as shown below.

Authentication with Fluid Attacks' platform API Token

In this authentication process, it is required to generate the platform API Token. The steps are explained below.

  1. Log in to https://app.fluidattacks.com
  2. Generate the API Token from the web application by going to the User information drop-down menu, by clicking on the option that says API.

Generate API Token

  1. Select an expiration date up to six months after the creation date:

Expiration Date

Note: Keep in mind that you can generate up to two API tokens.

  1. After clicking the “Confirm” button, you will see a string labeled “Access Token”. This will be your API Token:

Confirm Date

  1. Store this token safely, as it is the only time you will see it. With it, you can do the same things that you usually do on the web application.
  2. Now, enter the playground by browsing to https://app.fluidattacks.com/api
  3. Here, go to the bottom of the page and click on HTTP HEADERS.

Headers

  1. Type {"authorization":"Bearer API Token"}

Type

  1. Then you put the query of the request you want to make, click the “play” button to see the answer to that request.

Play Button

Examples

We will show you some examples with Python, Javascript and Bash.

First, we generate the script we want. Keep in mind that we will always use the POST method to request any necessary action. If you want to know more about this method, read more here.

In Python:

import requests
query = """
{
  me {
    userName
    userEmail
  }
}
"""
token = "YOUR_TOKEN_GOES_HERE"

response = requests.post(
  "https://app.fluidattacks.com/api",
  json={"query": query},
  headers={"authorization": f"Bearer {token}"},
)
print(response.json())

In JavaScript:

const response = await fetch("https://app.fluidattacks.com/api", {
headers: {
"content-type": "application/json",
authorization: "Bearer YOUR_TOKEN_GOES_HERE",
},
body: JSON.stringify({ query: "{ me { userName userEmail }}" }),
method: "POST",
});
console.log(await response.json());

In Bash:

curl \
--request POST \
--url https://app.fluidattacks.com/api \
--header "content-type: application/json" \
--header "authorization: Bearer YOUR_TOKEN_GOES_HERE" \
--data '{"query": "{ me { userName userEmail }}"}'

When you run the script, you will get what you requested from the query in the terminal. Please note that the token generated in the API is unique and confidential; we recommend not sharing this token.

Revoke token

When you want to revoke the API token, it is either because the token you generated has expired and you need a new one or because you lost the token (there is no way to see it after the first time) and you need a new one. To revoke, you have to go to the API Token in the drop-down menu in the platform, and there you will get a pop-up window where you are given the option to revoke the token.

Revoke token

Please note that if you are going to revoke the token because you do not remember it, you will get a warning which will tell you the last time you used it in the previous seven days.

Warning to revoke token

If you revoke it and generate a new one, keep in mind that the old token will no longer be valid and will no longer be usable in the implementations you have used it.

Now if you have never used the token or if the last time you used it was more than seven days ago, this confirmation message will not appear when you revoke it and generate a new one.

Playground Docs

In the playground, you have a tab called Docs, located on the left, where it will show you all the possible fields to build queries and all the possible mutations.

Playground

By clicking on it, you can continue to explore tab by tab all the operations that the API offers.

Playground Tab

We invite you to explore this documentation in the API playground.

Paginated fields

In the API, you will find two kinds of list fields. Some are paginated and others are not. The main difference between them is that non-paginated lists return all available results directly, returned as a normal list between square brackets.

Paginated Fields

While paginated lists, often identified by the suffix connection, return only a certain amount of results and a “cursor” that can be included in subsequent requests to advance through the pages.

Suffix Connection

It is important to keep these differences in mind when building integrations that need to retrieve all the information in a paginated field. We invite you read to more about it on GraphQL's official website here.

Let's review this example together. I want to validate the first ten vulnerabilities of the Narrabri group.

Paginated Example

When putting the range of the information that I want to bring me, the result will bring me these. If there is a next page in the last item of the query, there is hasNextPage and endCursor, which tells us that there is the next page and gives us its cursor token.

Item Query

To use the cursor, you can pass it as the argument after in the paginated field.

Argument After

You will be able to continue exploring the pages as long as hasNextPage is set to true. The GraphQL documentation offers more examples here.

Rate limits

You can make 100 requests per minute to the API. If this value is exceeded, it may fail the HTTP status code 429, accompanied by a header specifying the time to wait before making the next request.

It is recommended to handle that scenario in your script by reading the "retry-after" header, and waiting that amount of time before continuing. In this example, you can see how to control this scenario in a Python script.

import requests
from time import sleep
query = """
{
me {
userName
userEmail
}
}
"""
token = ""
def request():
while True:
response = requests.post(
"https://app.fluidattacks.com/api",
json={"query": query},
headers={"authorization": f"Bearer {token}"},
)
if response.status_code == 429:
seconds = response.headers["retry-after"]
sleep(seconds + 1)
else:
break
return response
response = request()
print(response.json())

This solution may vary depending on the HTTP client library or language of your preference. Waiting 1 additional second to the value indicated by the header is also advisable.

Temporary network errors

There may be moments where the API cannot respond in time due to high demand, connection failures, or other network-related issues.

It is recommended to implement a retrying strategy, where failed requests are performed again a certain amount of times, aiming to increase the resiliency of your integration. This is especially important when supporting mission-critical flows. Here’s a small example in a Python script.

MAX_RETRIES = 10

def request():
while True:
response = requests.post(
"https://app.fluidattacks.com/api",
json={"query": query},
headers={"authorization": f"Bearer {token}"},
)

if response.status_code == 429:
seconds = response.headers["retry-after"]
sleep(seconds + 1)
elif response.status >= 500:
retries += 1
if retries == MAX_RETRIES:
break
sleep(retries)
else:
break

return response

Remember that this solution may vary depending on the HTTP client library or language of your preference.

Fluid Attacks' platform API response status

When Fluid Attacks' platform API receives a request, it can respond with different status codes. Here are the most common ones.

CodeDescription
200The request has been processed. You can read more about the response body on GraphQL’s official website here.
400The request has a syntax error. Check the response for clues as to where it went wrong. Also, check https://graphql.org/learn/ to learn more about the GraphQL query syntax.
429The limit of requests per minute has been exceeded. Check the limits here. You can modify your logic to reduce the number of requests or implement a retrying strategy, waiting the time indicated in the "retry-after" header (in seconds).
502 - 504These errors can occur at times of high demand when the server cannot handle the request in time. They are usually temporary errors. We recommend implementing a retry mechanism. If the error persists, contact [email protected]

Response times

With GraphQL you can request a large amount of data in a single request, but you have to keep in mind that the response times will vary accordingly. Therefore it may be useful to split queries in different requests as needed.