You can authenticate to the Fluid Attacks API from the GraphiQL playground or by HTTP requests in code. This guide explains two possible ways of authentication through the GraphiQL playground.
You can choose to authenticate through Fluid Attacks' platform login:
You can go ahead and write the queries you need, and then click the play icon to execute them.
You can authenticate to Fluid Attacks' API with a token, which you have to generate on the platform. The steps are explained below.
{"authorization":"Bearer YOUR_TOKEN_GOES_HERE"}
. (Replace YOUR_TOKEN_GOES_HERE
with your actual token.)
Here are examples of how to make a simple query to the Fluid Attacks API using Python, JavaScript, and Bash. This query retrieves the current user's username and email. All examples use the POST
method to send the GraphQL query to the API endpoint. You can learn about this method reading the official GraphQL documentation.
YOUR_TOKEN_GOES_HERE
with your actual token.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())
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());
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 }}"}'
You might need to revoke an API token if it has expired or you have lost it. Follow these steps to revoke the token:
The GraphiQL playground provides built-in documentation to help you explore the API:
The Fluid Attacks API uses both paginated and non-paginated lists. Non-paginated lists return all available results directly, as a normal list, and between square brackets. An example is shown in the screenshot below.
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. Read the GraphQL's official pagination documentation for more information.
Consider this example to better understand pagination: Retrieving the first ten vulnerabilities of a group named Narrabri. The query is shown in the screenshot below.
Explore the terminal. If there is a next page in the last item of the query, you can see hasNextPage
and endCursor
, where the former informs there is a next page and the latter provides its cursor token.
To see the next page, you can pass the cursor token as the argument after
in your next query.
Continue making requests with the updated after
argument until hasNextPage
is false, indicating that you have retrieved all pages. See other examples in the GraphQL documentation.
The Fluid Attacks API has a rate limit of 100 requests per minute. If you exceed this limit, you receive an HTTP 429 (Too Many Requests) error response. The response includes a retry-after
header indicating how long to wait before making another request.
See how to control this scenario with 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.
The Fluid Attacks API may occasionally experience temporary network issues, such as timeouts due to high demand or connection failures.
To make your integration more resilient, implement a retry mechanism for failed requests. This is especially crucial for mission-critical processes that rely on the API. The following is 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 the above solution may vary depending on the HTTP client library or language of your preference.
The Fluid Attacks platform API uses standard HTTP status codes to indicate the success or failure of your requests. Here are some of the most common codes you might encounter:
Status code
|
Description
|
200
|
OK: The request has been processed. You can learn more about the structure of the response body in the GraphQL documentation.
|
400
|
Bad Request: The request has a syntax error or is malformed. Check the response body for details about the error. Refer to the GraphQL documentation for guidance on proper query syntax.
|
429
|
Too Many Requests: You have exceeded the API rate limit (100 requests per minute). Reduce the frequency of your requests or implement a retry mechanism with exponential backoff, respecting the retry-after header value (in seconds) provided in the response.
|
502-504
|
Bad Gateway / Gateway Timeout: These errors usually indicate temporary server issues or network problems. Implement a retry mechanism in your code. If the errors persist, please contact help@fluidattacks.com.
|