Truss API Guide
Using the API
The Truss API facilitates powerful endpoint query operations to provide access to Truss' security data. The API is designed to be used by developers to retrieve, filter, and analyze data efficiently.
Truss allows organizations to access the security data they need, in a way that is efficient and easy to use.
Truss Search Endpoint
The Truss /product/search
endpoint is designed to accommodate most data access needs. This endpoint allows you to retrieve comprehensive slices of security data based on a variety of filter parameters.
- curl
- javascript
- python
- ruby
- go
- rust
curl -X 'POST' \
"https://api.truss-security.com/product/search" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"days": 2
}'
import axios from 'axios';
const YOUR_API_KEY = 'YOUR_API_KEY';
async function searchProducts() {
try {
const response = await axios({
method: 'POST',
url: 'https://api.truss-security.com/product/search',
headers: {
'x-api-key': YOUR_API_KEY,
'Content-Type': 'application/json'
},
data: {
days: 2
}
});
return response.data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
import requests
import json
API_KEY = 'YOUR_API_KEY'
def search_products():
url = 'https://api.truss-security.com/product/search'
headers = {
'x-api-key': API_KEY,
'Content-Type': 'application/json'
}
data = {
'days': 2
}
try:
response = requests.post(url, headers=headers, json=data)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
raise
require 'net/http'
require 'uri'
require 'json'
API_KEY = 'YOUR_API_KEY'
def search_products
uri = URI('https://api.truss-security.com/product/search')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = API_KEY
request['Content-Type'] = 'application/json'
request.body = { days: 2 }.to_json
begin
response = http.request(request)
JSON.parse(response.body)
rescue StandardError => e
puts "Error: #{e.message}"
raise
end
end
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const apiKey = "YOUR_API_KEY"
type SearchRequest struct {
Days int `json:"days"`
}
func searchProducts() (map[string]interface{}, error) {
url := "https://api.truss-security.com/product/search"
data := SearchRequest{Days: 2}
jsonData, err := json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("error marshaling JSON: %v", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
}
req.Header.Set("x-api-key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
}
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("error parsing response: %v", err)
}
return result, nil
}
use reqwest::Client;
use serde_json::{json, Value};
use anyhow::Result;
const API_KEY: &str = "YOUR_API_KEY";
async fn search_products() -> Result<Value> {
let client = Client::new();
let response = client
.post("https://api.truss-security.com/product/search")
.header("x-api-key", API_KEY)
.header("Content-Type", "application/json")
.json(&json!({
"days": 2
}))
.send()
.await?;
let data = response.json::<Value>().await?;
Ok(data)
}
Search by Date
There are several ways to search by date. The following parameters are supported:
- startdate: Return products uploaded on or after this date.
- enddate: Return products uploaded on or before this date.
- days: Return products uploaded since N days ago.
Searches may be time boxed using the startdate
and enddate
parameters. Different date formats are supported:
- unix epoch time in milliseconds (e.g., "1717379710282")
- ISO format (e.g., "2024-06-02")
- Human readable format (e.g., "March 20, 2024")
For example, the following example will return all security products entered since the specified start date (Sun Jun 2 2024) and before the specified end date (Mon Jun 3 2024).
- curl
- javascript
- python
- ruby
- go
- rust
curl -X 'POST' \
"https://api.truss-security.com/product/search" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"startDate": "2024-06-02",
"endDate": "2024-06-03"
}'
import axios from 'axios';
const YOUR_API_KEY = 'YOUR_API_KEY';
async function searchByDate() {
try {
const response = await axios({
method: 'POST',
url: 'https://api.truss-security.com/product/search',
headers: {
'x-api-key': YOUR_API_KEY,
'Content-Type': 'application/json'
},
data: {
startDate: "2024-06-02",
endDate: "2024-06-03"
}
});
return response.data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
import requests
import json
API_KEY = 'YOUR_API_KEY'
def search_by_date():
url = 'https://api.truss-security.com/product/search'
headers = {
'x-api-key': API_KEY,
'Content-Type': 'application/json'
}
data = {
'startDate': '2024-06-02',
'endDate': '2024-06-03'
}
try:
response = requests.post(url, headers=headers, json=data)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
raise
require 'net/http'
require 'uri'
require 'json'
API_KEY = 'YOUR_API_KEY'
def search_by_date
uri = URI('https://api.truss-security.com/product/search')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = API_KEY
request['Content-Type'] = 'application/json'
request.body = {
startDate: '2024-06-02',
endDate: '2024-06-03'
}.to_json
begin
response = http.request(request)
JSON.parse(response.body)
rescue StandardError => e
puts "Error: #{e.message}"
raise
end
end
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const apiKey = "YOUR_API_KEY"
type DateSearchRequest struct {
StartDate string `json:"startDate"`
EndDate string `json:"endDate"`
}
func searchByDate() (map[string]interface{}, error) {
url := "https://api.truss-security.com/product/search"
data := DateSearchRequest{
StartDate: "2024-06-02",
EndDate: "2024-06-03",
}
jsonData, err := json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("error marshaling JSON: %v", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
}
req.Header.Set("x-api-key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
}
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("error parsing response: %v", err)
}
return result, nil
}
use reqwest::Client;
use serde_json::{json, Value};
use anyhow::Result;
const API_KEY: &str = "YOUR_API_KEY";
async fn search_by_date() -> Result<Value> {
let client = Client::new();
let response = client
.post("https://api.truss-security.com/product/search")
.header("x-api-key", API_KEY)
.header("Content-Type", "application/json")
.json(&json!({
"startDate": "2024-06-02",
"endDate": "2024-06-03"
}))
.send()
.await?;
let data = response.json::<Value>().await?;
Ok(data)
}
#[tokio::main]
async fn main() -> Result<()> {
match search_by_date().await {
Ok(data) => println!("Response: {:?}", data),
Err(e) => eprintln!("Error: {}", e),
}
Ok(())
}
If a days
parameter is included the search returns security products entered since that number of days in the past to the current time. This parameter will be used in place of startdate
and enddate
parameters.
When a days
parameter is entered, startdate
and enddate
parameters will be ignored.
- curl
- javascript
- python
- ruby
- go
- rust
curl -X 'POST' \
"https://api.truss-security.com/product/search" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"days": 3
}'
import axios from 'axios';
const YOUR_API_KEY = 'YOUR_API_KEY';
async function searchByDays() {
try {
const response = await axios({
method: 'POST',
url: 'https://api.truss-security.com/product/search',
headers: {
'x-api-key': YOUR_API_KEY,
'Content-Type': 'application/json'
},
data: {
days: 3
}
});
return response.data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
import requests
import json
API_KEY = 'YOUR_API_KEY'
def search_by_days():
url = 'https://api.truss-security.com/product/search'
headers = {
'x-api-key': API_KEY,
'Content-Type': 'application/json'
}
data = {
'days': 3
}
try:
response = requests.post(url, headers=headers, json=data)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
raise
require 'net/http'
require 'uri'
require 'json'
API_KEY = 'YOUR_API_KEY'
def search_by_days
uri = URI('https://api.truss-security.com/product/search')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = API_KEY
request['Content-Type'] = 'application/json'
request.body = { days: 3 }.to_json
begin
response = http.request(request)
JSON.parse(response.body)
rescue StandardError => e
puts "Error: #{e.message}"
raise
end
end
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const apiKey = "YOUR_API_KEY"
type DaysSearchRequest struct {
Days int `json:"days"`
}
func searchByDays() (map[string]interface{}, error) {
url := "https://api.truss-security.com/product/search"
data := DaysSearchRequest{Days: 3}
jsonData, err := json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("error marshaling JSON: %v", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
}
req.Header.Set("x-api-key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
}
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("error parsing response: %v", err)
}
return result, nil
}
use reqwest::Client;
use serde_json::{json, Value};
use anyhow::Result;
const API_KEY: &str = "YOUR_API_KEY";
async fn search_by_days() -> Result<Value> {
let client = Client::new();
let response = client
.post("https://api.truss-security.com/product/search")
.header("x-api-key", API_KEY)
.header("Content-Type", "application/json")
.json(&json!({
"days": 3
}))
.send()
.await?;
let data = response.json::<Value>().await?;
Ok(data)
}
#[tokio::main]
async fn main() -> Result<()> {
match search_by_days().await {
Ok(data) => println!("Response: {:?}", data),
Err(e) => eprintln!("Error: {}", e),
}
Ok(())
}
Boolean Search Filters
Boolean search filters can be used to narrow down the results of a query. Boolean search filters contain both the date parameters and the product parameters and are passed directly into the data field of the search request.
The following product parameters support boolean search filters:
- category: Array of category names (e.g., ["Ransomware", "OSINT"]).
- source: Array of source names (e.g., ["TOR Project"]).
- author: Array of author names (e.g., ["MohitK_"]).
- industry: Array of industry names (e.g., ["Finance"]).
- region: Array of region names (e.g., ["Europe"]).
- reference: Array of reference strings (e.g., ["https://threatview.io/"]).
- tags: Array of tags (e.g., ["C2", "AlphV"]).
'OR' Filtering
When searching for multiple values for a single parameter, the search performs an OR
between the strings passed as an array to a single parameter. For example, if the values ["Ransomware", "OSINT"] are passed to the category
parameter, the search will return all security products where the category
is "Ransomware" OR "OSINT".
'AND' Filtering
If more than one parameter is specified in a search (e.g., category
and source
), then the search will return those products that satisfy BOTH of the specified parameters. In other words, the search performs an AND
between the different parameters.
For example, if ["Ransomeware"] is passed to the category
parameter and the ["TOR Project"] is passed to the source
parameter, the search will return all security products where the category
is "Ransomeware" AND where the source
is "TOR Project".
Consider the following filter:
- curl
- javascript
- python
- ruby
- go
- rust
curl -X 'POST' \
"https://api.truss-security.com/product/search" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"days": 3,
"author": ["TOR Project"],
"tags": ["C2", "AlphV"]
}'
import axios from 'axios';
const YOUR_API_KEY = 'YOUR_API_KEY';
async function searchWithFilters() {
try {
const response = await axios({
method: 'POST',
url: 'https://api.truss-security.com/product/search',
headers: {
'x-api-key': YOUR_API_KEY,
'Content-Type': 'application/json'
},
data: {
days: 3,
author: ["TOR Project"],
tags: ["C2", "AlphV"]
}
});
return response.data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
import requests
import json
API_KEY = 'YOUR_API_KEY'
def search_with_filters():
url = 'https://api.truss-security.com/product/search'
headers = {
'x-api-key': API_KEY,
'Content-Type': 'application/json'
}
data = {
'days': 3,
'author': ['TOR Project'],
'tags': ['C2', 'AlphV']
}
try:
response = requests.post(url, headers=headers, json=data)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
raise
require 'net/http'
require 'uri'
require 'json'
API_KEY = 'YOUR_API_KEY'
def search_with_filters
uri = URI('https://api.truss-security.com/product/search')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = API_KEY
request['Content-Type'] = 'application/json'
request.body = {
days: 3,
author: ['TOR Project'],
tags: ['C2', 'AlphV']
}.to_json
begin
response = http.request(request)
JSON.parse(response.body)
rescue StandardError => e
puts "Error: #{e.message}"
raise
end
end
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const apiKey = "YOUR_API_KEY"
type FilterSearchRequest struct {
Days int `json:"days"`
Author []string `json:"author"`
Tags []string `json:"tags"`
}
func searchWithFilters() (map[string]interface{}, error) {
url := "https://api.truss-security.com/product/search"
data := FilterSearchRequest{
Days: 3,
Author: []string{"TOR Project"},
Tags: []string{"C2", "AlphV"},
}
jsonData, err := json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("error marshaling JSON: %v", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
}
req.Header.Set("x-api-key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
}
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("error parsing response: %v", err)
}
return result, nil
}
use reqwest::Client;
use serde_json::{json, Value};
use anyhow::Result;
const API_KEY: &str = "YOUR_API_KEY";
async fn search_with_filters() -> Result<Value> {
let client = Client::new();
let response = client
.post("https://api.truss-security.com/product/search")
.header("x-api-key", API_KEY)
.header("Content-Type", "application/json")
.json(&json!({
"days": 3,
"author": ["TOR Project"],
"tags": ["C2", "AlphV"]
}))
.send()
.await?;
let data = response.json::<Value>().await?;
Ok(data)
}
#[tokio::main]
async fn main() -> Result<()> {
match search_with_filters().await {
Ok(data) => println!("Response: {:?}", data),
Err(e) => eprintln!("Error: {}", e),
}
Ok(())
}
Paging
When a product search results in a large number of products, only a subset of the total will be returned by each call to the /product/search
endpoint. In these cases, the initial calls will return metadata in the form of a LastEvaluatedKey
that can be used to page through the results.
- curl
- javascript
- python
- ruby
- go
- rust
curl -X 'POST' \
"https://api.truss-security.com/product/search" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"days": 2,
"LastEvaluatedKey": {
"GSI1PK": "PROD",
"SK": "VER#0",
"GSI1SK": 1717377712019,
"PK": "PROD#01HKDT164VYRS50ZQ8RJEHHBH0"
}
}'
import axios from 'axios';
const YOUR_API_KEY = 'YOUR_API_KEY';
export const trussApi = async (filter) => {
const server = 'https://api.truss-security.com'
const searchEndpoint = '/product/search'
const url = server + searchEndpoint
try {
const options = {
method: 'POST',
headers: {
'x-api-key': YOUR_API_KEY
},
data: filter,
url,
};
const response = await axios(options);
return response.data
} catch (err) {
console.log('HTTP Error: ', err)
throw err
}
}
export async function fetchAllPages(filter) {
const allItems = [];
let lastEvaluatedKey;
try {
do {
const currentFilter = {
...filter,
LastEvaluatedKey: lastEvaluatedKey
};
const { result } = await trussApi(currentFilter);
allItems.push(...result.Items);
lastEvaluatedKey = result.LastEvaluatedKey;
} while (lastEvaluatedKey);
return allItems;
} catch (error) {
throw new Error(`Failed to fetch pages: ${error.message}`);
}
}
import requests
import json
API_KEY = 'YOUR_API_KEY'
def fetch_all_pages(filter_params):
url = 'https://api.truss-security.com/product/search'
headers = {
'x-api-key': API_KEY,
'Content-Type': 'application/json'
}
all_items = []
last_evaluated_key = None
try:
while True:
if last_evaluated_key:
filter_params['LastEvaluatedKey'] = last_evaluated_key
response = requests.post(url, headers=headers, json=filter_params)
response.raise_for_status()
result = response.json()['result']
all_items.extend(result['Items'])
last_evaluated_key = result.get('LastEvaluatedKey')
if not last_evaluated_key:
break
return all_items
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
raise
require 'net/http'
require 'uri'
require 'json'
API_KEY = 'YOUR_API_KEY'
def fetch_all_pages(filter_params)
uri = URI('https://api.truss-security.com/product/search')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
all_items = []
last_evaluated_key = nil
begin
loop do
filter_params['LastEvaluatedKey'] = last_evaluated_key if last_evaluated_key
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = API_KEY
request['Content-Type'] = 'application/json'
request.body = filter_params.to_json
response = http.request(request)
result = JSON.parse(response.body)['result']
all_items.concat(result['Items'])
last_evaluated_key = result['LastEvaluatedKey']
break unless last_evaluated_key
end
all_items
rescue StandardError => e
puts "Error: #{e.message}"
raise
end
end
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const apiKey = "YOUR_API_KEY"
type SearchRequest struct {
Days int `json:"days"`
LastEvaluatedKey map[string]interface{} `json:"LastEvaluatedKey,omitempty"`
}
func fetchAllPages(filter SearchRequest) ([]map[string]interface{}, error) {
url := "https://api.truss-security.com/product/search"
var allItems []map[string]interface{}
for {
jsonData, err := json.Marshal(filter)
if err != nil {
return nil, fmt.Errorf("error marshaling JSON: %v", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
}
req.Header.Set("x-api-key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
}
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("error parsing response: %v", err)
}
resultData := result["result"].(map[string]interface{})
items := resultData["Items"].([]interface{})
for _, item := range items {
allItems = append(allItems, item.(map[string]interface{}))
}
lastEvaluatedKey, exists := resultData["LastEvaluatedKey"]
if !exists || lastEvaluatedKey == nil {
break
}
filter.LastEvaluatedKey = lastEvaluatedKey.(map[string]interface{})
}
return allItems, nil
}
use reqwest::Client;
use serde_json::{json, Value};
use anyhow::Result;
const API_KEY: &str = "YOUR_API_KEY";
async fn fetch_all_pages(mut filter: Value) -> Result<Vec<Value>> {
let client = Client::new();
let mut all_items = Vec::new();
loop {
let response = client
.post("https://api.truss-security.com/product/search")
.header("x-api-key", API_KEY)
.header("Content-Type", "application/json")
.json(&filter)
.send()
.await?;
let result = response.json::<Value>().await?;
let items = result["result"]["Items"].as_array()
.ok_or_else(|| anyhow::anyhow!("Invalid response format"))?;
all_items.extend(items.clone());
if let Some(last_key) = result["result"]["LastEvaluatedKey"].as_object() {
filter["LastEvaluatedKey"] = json!(last_key);
} else {
break;
}
}
Ok(all_items)
}
#[tokio::main]
async fn main() -> Result<()> {
let filter = json!({
"days": 2
});
match fetch_all_pages(filter).await {
Ok(items) => println!("Total items: {}", items.len()),
Err(e) => eprintln!("Error: {}", e),
}
Ok(())
}
Last Evaluated Keys
When working with large datasets, the Truss API implements pagination to ensure efficient data retrieval. If your query returns a LastEvaluatedKey
in the response, this indicates there are more results available. To retrieve the next set of results, include this key in your subsequent query.
The LastEvaluatedKey
acts as a bookmark, telling the API where to resume fetching results. This pagination mechanism ensures optimal performance while allowing you to retrieve complete result sets.
Initial Query Examples
- curl
- javascript
- python
- ruby
- go
- rust
curl -X 'POST' \
"https://api.truss-security.com/product/search" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"startdate": 1733616000000,
"enddate": 1733961599999,
"source": [
"OpenPhish"
]
}' | jq
import axios from 'axios';
const YOUR_API_KEY = 'YOUR_API_KEY';
async function searchProducts() {
try {
const response = await axios({
method: 'POST',
url: 'https://api.truss-security.com/product/search',
headers: {
'x-api-key': YOUR_API_KEY,
'Content-Type': 'application/json'
},
data: {
startdate: 1733616000000,
enddate: 1733961599999,
source: ["OpenPhish"]
}
});
return response.data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
import requests
import json
API_KEY = 'YOUR_API_KEY'
def search_products():
url = 'https://api.truss-security.com/product/search'
headers = {
'x-api-key': API_KEY,
'Content-Type': 'application/json'
}
data = {
'startdate': 1733616000000,
'enddate': 1733961599999,
'source': ['OpenPhish']
}
try:
response = requests.post(url, headers=headers, json=data)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
raise
require 'net/http'
require 'uri'
require 'json'
API_KEY = 'YOUR_API_KEY'
def search_products
uri = URI('https://api.truss-security.com/product/search')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = API_KEY
request['Content-Type'] = 'application/json'
request.body = {
startdate: 1733616000000,
enddate: 1733961599999,
source: ['OpenPhish']
}.to_json
begin
response = http.request(request)
JSON.parse(response.body)
rescue StandardError => e
puts "Error: #{e.message}"
raise
end
end
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const apiKey = "YOUR_API_KEY"
type SearchRequest struct {
StartDate int64 `json:"startdate"`
EndDate int64 `json:"enddate"`
Source []string `json:"source"`
}
func searchProducts() (map[string]interface{}, error) {
url := "https://api.truss-security.com/product/search"
data := SearchRequest{
StartDate: 1733616000000,
EndDate: 1733961599999,
Source: []string{"OpenPhish"},
}
jsonData, err := json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("error marshaling JSON: %v", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
}
req.Header.Set("x-api-key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
}
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("error parsing response: %v", err)
}
return result, nil
}
use reqwest::Client;
use serde_json::{json, Value};
use anyhow::Result;
const API_KEY: &str = "YOUR_API_KEY";
async fn search_products() -> Result<Value> {
let client = Client::new();
let response = client
.post("https://api.truss-security.com/product/search")
.header("x-api-key", API_KEY)
.header("Content-Type", "application/json")
.json(&json!({
"startdate": 1733616000000,
"enddate": 1733961599999,
"source": ["OpenPhish"]
}))
.send()
.await?;
let data = response.json::<Value>().await?;
Ok(data)
}
When using the curl command, the API returns a response containing a LastEvaluatedKey, it will look like this:
{ "LastEvaluatedKey": { "SK": "VER#0", "GSI3PK": "OpenPhish", "PK": "PROD#01JEMBFNT12JV97ZT3GVBF2X2J", "GSI3SK": 1733702440770 } }
Using LastEvaluatedKey Examples
- curl
- javascript
- python
- ruby
- go
- rust
curl -X 'POST' \
"https://api.truss-security.com/product/search" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"startdate": 1733616000000,
"enddate": 1733961599999,
"source": [
"OpenPhish"
],
"LastEvaluatedKey": {
"SK": "VER#0",
"GSI3PK": "OpenPhish",
"PK": "PROD#01JEMBFNT12JV97ZT3GVBF2X2J",
"GSI3SK": 1733702440770
}
}' | jq
import axios from 'axios';
const YOUR_API_KEY = 'YOUR_API_KEY';
async function fetchAllResults() {
const baseQuery = {
startdate: 1733616000000,
enddate: 1733961599999,
source: ["OpenPhish"]
};
try {
// Initial query
let response = await axios({
method: 'POST',
url: 'https://api.truss-security.com/product/search',
headers: {
'x-api-key': YOUR_API_KEY,
'Content-Type': 'application/json'
},
data: baseQuery
});
let results = response.data;
// If LastEvaluatedKey exists, fetch next page
if (results.LastEvaluatedKey) {
const nextQuery = {
...baseQuery,
LastEvaluatedKey: results.LastEvaluatedKey
};
response = await axios({
method: 'POST',
url: 'https://api.truss-security.com/product/search',
headers: {
'x-api-key': YOUR_API_KEY,
'Content-Type': 'application/json'
},
data: nextQuery
});
}
return response.data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
import requests
import json
API_KEY = 'YOUR_API_KEY'
def fetch_all_results():
url = 'https://api.truss-security.com/product/search'
headers = {
'x-api-key': API_KEY,
'Content-Type': 'application/json'
}
base_query = {
'startdate': 1733616000000,
'enddate': 1733961599999,
'source': ['OpenPhish']
}
try:
# Initial query
response = requests.post(url, headers=headers, json=base_query)
response.raise_for_status()
results = response.json()
# If LastEvaluatedKey exists, fetch next page
if 'LastEvaluatedKey' in results:
next_query = base_query.copy()
next_query['LastEvaluatedKey'] = results['LastEvaluatedKey']
response = requests.post(url, headers=headers, json=next_query)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
raise
require 'net/http'
require 'uri'
require 'json'
API_KEY = 'YOUR_API_KEY'
def fetch_all_results
uri = URI('https://api.truss-security.com/product/search')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
base_query = {
startdate: 1733616000000,
enddate: 1733961599999,
source: ['OpenPhish']
}
begin
# Initial query
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = API_KEY
request['Content-Type'] = 'application/json'
request.body = base_query.to_json
response = http.request(request)
results = JSON.parse(response.body)
# If LastEvaluatedKey exists, fetch next page
if results['LastEvaluatedKey']
next_query = base_query.merge({
'LastEvaluatedKey' => results['LastEvaluatedKey']
})
request.body = next_query.to_json
response = http.request(request)
end
JSON.parse(response.body)
rescue StandardError => e
puts "Error: #{e.message}"
raise
end
end
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const apiKey = "YOUR_API_KEY"
type QueryRequest struct {
StartDate int64 `json:"startdate"`
EndDate int64 `json:"enddate"`
Source []string `json:"source"`
LastEvaluatedKey map[string]interface{} `json:"LastEvaluatedKey,omitempty"`
}
func fetchAllResults() (map[string]interface{}, error) {
url := "https://api.truss-security.com/product/search"
baseQuery := QueryRequest{
StartDate: 1733616000000,
EndDate: 1733961599999,
Source: []string{"OpenPhish"},
}
// Initial query
jsonData, err := json.Marshal(baseQuery)
if err != nil {
return nil, fmt.Errorf("error marshaling JSON: %v", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
}
req.Header.Set("x-api-key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
}
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("error parsing response: %v", err)
}
// If LastEvaluatedKey exists, fetch next page
if lastKey, exists := result["LastEvaluatedKey"].(map[string]interface{}); exists {
baseQuery.LastEvaluatedKey = lastKey
jsonData, _ = json.Marshal(baseQuery)
req, _ = http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Set("x-api-key", apiKey)
req.Header.Set("Content-Type", "application/json")
resp, err = client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
body, _ = ioutil.ReadAll(resp.Body)
json.Unmarshal(body, &result)
}
return result, nil
}
use reqwest::Client;
use serde_json::{json, Value};
use anyhow::Result;
const API_KEY: &str = "YOUR_API_KEY";
async fn fetch_all_results() -> Result<Value> {
let client = Client::new();
let base_query = json!({
"startdate": 1733616000000,
"enddate": 1733961599999,
"source": ["OpenPhish"]
});
// Initial query
let response = client
.post("https://api.truss-security.com/product/search")
.header("x-api-key", API_KEY)
.header("Content-Type", "application/json")
.json(&base_query)
.send()
.await?;
let mut result = response.json::<Value>().await?;
// If LastEvaluatedKey exists, fetch next page
if let Some(last_key) = result["LastEvaluatedKey"].as_object() {
let mut next_query = base_query.as_object().unwrap().clone();
next_query.insert("LastEvaluatedKey".to_string(), json!(last_key));
let response = client
.post("https://api.truss-security.com/product/search")
.header("x-api-key", API_KEY)
.header("Content-Type", "application/json")
.json(&next_query)
.send()
.await?;
result = response.json::<Value>().await?;
}
Ok(result)
}
Pro API Tips
Advanced API Techniques
- Pagination: Handle large result sets efficiently by adding pagination to your client
- Filter Chaining: Combine multiple filters for precise results
- Date Formatting: You can use various date formats for flexibility. epoch, day range, or human readable
- Error Handling: Implement robust error handling through your client to handle errors gracefully
API Best Practices
- Cache responses when appropriate
- Implement rate limiting in your client
- Use proper error handling and retries
- Your API key is sensitive to your account. Do not share it with anyone.
The Truss API is your tool for accessing and managing security intelligence data. Use these endpoints to retrieve, filter, and analyze data efficiently.