Gravwell provides a REST API that provides access to the Gravwell query system. This API can be used to automate integrations with external tools. This document will provide an example script for using Gravwell's REST API for automation.
Resources:
- Gravwell Docs: API Token System: For additional information on Token Generation
- Gravwell Docs: Gravwell Direct Query API: For additional methods of Querying the API
- Gravwell Docs: Automation Script API & Examples: For additional Automation Examples
- Gravwell API: For a complete list of currently supported API calls
- Gravwell Blog: The basics of Gravwell API Access Tokens: Provides another example of using the API to create
Generate an API Token
The Tokens API interface is located in the “Tools & Resources” navigation section.
The default interface of the Tokens API page shows all the currently constructed tokens, both expired and not.
Select Add Token
Permissions can be selected in groups or as fine controls. For example, you can select the “Search and Data” group which will automatically fill in all the API permissions required to interact with the search system. This includes executing searches, getting the search history, downloading, saving, and attaching to searches.
After populating your new token with a name, description, permissions, and an optional expiration it is time to actually make the token by clicking the Save button. At this point Gravwell will create the token and provide it to you. Copy this token for use in your code. !NOTE: This token will never be provided again and can only be regenerated.
Querying Data
To test the API Token you can use curl to run a search, this will run the query 'tag=gravwell limit 10' over the last 24h and output as csv:
curl -X POST \
-H "Gravwell-Token: HmrAgIKlKP6hCGBJvFIABUFFyrdyTwrIlmlHH4a4cynwSBF5EFA" \
-H "query: tag=gravwell limit 10" \
-H "duration: 24h" \
-H "format: csv" \
http://127.0.0.1:8080/api/search/direct
Example Output:
Example Scripts
The following is a few scripts each shows a similar simple example where we query the API and write the results to an output file.
Example Bash Script:
#!/usr/bin/env bash ### GLOBALS # Define the API token for authentication with the Gravwell server GRAVWELL_API_TOKEN="HmrAgIKlKP6hCGBJvFIABUFFyrdyTwrIlmlHH4a4cynwSBF5EFA" # Define the Gravwell server URL and port GRAVWELL_SERVER="127.0.0.1:8080" # Generate a timestamp for the filename to ensure each report is uniquely named DATE=$(date +%Y_%b_%d_%H:%M) # Function to query data from Gravwell and save it as a CSV file get_gravwell(){ # Define the query to use for the API request gravwell_query="tag=gravwell limit 10" # Define the URL of the Gravwell Web Server to send the API request url="http://$GRAVWELL_SERVER/api/search/direct" # Use curl to query the API # - The request is silent and does not show progress or error messages # - The HTTP response code is captured and stored in 'resp' # - The output is saved to a CSV file named with the current date and time resp=$(curl --silent --write-out "%{http_code}" \ --output "./${DATE}_GravwelReport.csv" \ -X POST \ -H "Gravwell-Token: $GRAVWELL_API_TOKEN" \ -H "query: $gravwell_query" \ -H "duration: 24h" \ -H "format: csv" \ $url ) # Check the HTTP response code if [ $resp == "200" ]; then # Print success message if HTTP code is 200 echo "[INFO] API call successful" else # Print error message if request was not successful echo "[ERROR] API call unsuccessful server responded with HTTP code: $resp" fi } # Call the function to execute the API request get_gravwell
Example Python Script
#!/usr/bin/env python3 import requests from datetime import datetime ### GLOBALS # Define the API token for authentication with the Gravwell server GRAVWELL_API_TOKEN="HmrAgIKlKP6hCGBJvFIABUFFyrdyTwrIlmlHH4a4cynwSBF5EFA" # Define the Gravwell server URL and port GRAVWELL_SERVER="127.0.0.1:8080" # Generate a timestamp for the filename to ensure each report is uniquely named DATE=datetime.now().strftime('%Y_%b_%d_%H:%M') # Function to query data from Gravwell and save it as a text file def get_gravwell(): # Define the query to use for the API request gravwell_query="tag=gravwell limit 10" # Define the URL of the Gravwell Web Server to send the API request url = f"http://{GRAVWELL_SERVER}/api/search/direct" headers = { 'Gravwell-Token': f'{GRAVWELL_API_TOKEN}', 'query': f'{gravwell_query}', 'duration': '24h', 'format': 'text' } # Use response to query the API response = requests.post(url, headers=headers) # Check the HTTP response code to determine if the request was successful if response.status_code == 200: # Write HTML response to file with open(f"{DATE}_GravwellReport.txt", "w") as f: f.write(response.text) # Print success message if HTTP code is 200 print("[INFO] API call successful") else: # Print error message if request was not successful print(f"[ERROR] API call unsuccessful server responded with HTTP code: {response.status_code}") def main(): # Call the function to execute the API request get_gravwell() if __name__ == "__main__": main()
Example Go Script
package main import ( "crypto/tls" "fmt" "io" "net/http" "os" "time" ) // GLOBALS // Define the API token for authentication with the Gravwell server var GRAVWELL_API_TOKEN = "HmrAgIKlKP6hCGBJvFIABUFFyrdyTwrIlmlHH4a4cynwSBF5EFA" // Define the Gravwell server URL and port var GRAVWELL_SERVER = "127.0.0.1:8080" // Generate a timestamp for the filename to ensure each report is uniquely named var DATE = time.Now().Format("2006_01_02_15_04") // Function to query data from Gravwell and save it as a json file func get_gravwell() { // Define the query to use for the API request gravwell_query := "tag=gravwell limit 10" // Define the URL of the Gravwell Web Server to send the API request url := "http://" + GRAVWELL_SERVER + "/api/search/direct" request, err := http.NewRequest(http.MethodPost, url, nil) if err != nil { fmt.Printf("[ERROR] client: could not create request: %s\n", err) os.Exit(1) } request.Header.Add("Gravwell-Token", GRAVWELL_API_TOKEN) request.Header.Add("query", gravwell_query) request.Header.Add("duration", "24h") request.Header.Add("format", "json") tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} client := http.Client{Transport: tr} // Use response to query the API response, err := client.Do((request)) if err != nil { fmt.Printf("[ERROR] sending Request: %v\n", err) return } defer response.Body.Close() // Check the HTTP response code to determine if the request was successful if response.StatusCode == 200 { // Write HTML response to file f, err := os.Create(DATE + "_GravwellReport.json") if err != nil { fmt.Printf("[ERROR] Error creating output file\n") return } defer f.Close() io.Copy(f, response.Body) // Print success message if HTTP code is 200 fmt.Printf("[INFO] API call successful\n") } else { // Print error message if request was not successful fmt.Printf("[ERROR] API call unsuccessful server responded with HTTP code:" + string(response.StatusCode) + "\n") } } func main() { get_gravwell() }
Conclusion
Gravwell’s REST API allows you to automate your data queries, manage saved queries, and integrate Gravwell with other tools and systems. By following this guide, you should be able to get started with basic API interactions and incorporate them into your automation workflows.
For more detailed information, refer to the Gravwell API documentation or reach out to us through your customer support representative or our Discord.
Was this article helpful?
That’s Great!
Thank you for your feedback
Sorry! We couldn't be helpful
Thank you for your feedback
Feedback sent
We appreciate your effort and will try to fix the article