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.
Here the authentication is done through Fluid Attacks' platform login, these are the following steps:
You can write the queries you need, and then click the “play” button to get the answer to your request.
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.
In this authentication process, it is required to generate the platform API Token. The steps are explained below.
{"authorization":"Bearer API Token"}
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.
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.
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.
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.
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.
By clicking on it, you can continue to explore tab by tab all the operations that the API offers.
We invite you to explore this documentation in the API playground.
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.
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.
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.
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.
To use the cursor, you can pass it as the argument after
in the paginated field.
You will be able to continue exploring the pages as long as hasNextPage
is set to true. The GraphQL documentation offers more examples here.
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.
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.
When Fluid Attacks' platform API receives a request, it can respond with different status codes. Here are the most common ones.
Code
|
Description
|
200
|
The request has been processed. You can read more about the response body on GraphQL’s official website here.
|
400
|
The 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.
|
429
|
The 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-504
|
These 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 help@fluidattacks.com.
|