Querying

Queries allow you to check whether FraudHosting has records for a given customer identity. Queries use the form endpoint and return a compact text payload that you must parse.

Submit a Query

Endpoint: POST https://api.fraud.hosting/api/

Payload:

FieldDescription
_apiReporter API key.
_actionMust be query.
<data*>One or more hashed identifiers (email, phone…).

You can reuse the hashing algorithm from the hashing guide. Duplicate keys should be suffixed with numbers (email, email2, email3). During submission the application maintains the original order.

Response Format

The body is a hyphen-delimited string:

<Points>-<Reported>-<Reliability>-<link>
SegmentMeaning
PointsWeighted score for the submitted identifiers (higher is riskier).
ReportedNumber of matching reports in the database.
ReliabilityConfidence indicator (0–10, higher is more reliable).
linkPublic URL with detailed report information.

Always display the link in your UI, even when other values are zero.

curl https://api.fraud.hosting/api/ \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "_api=a51ff508c331b7e9&_action=query&email=ddb48c18cf40686416e811256b47c6f96485d70a"
$payload = http_build_query([
  '_api'    => $apiKey,
  '_action' => 'query',
  'email'   => fraudhosting_hash('client@example.com'),
  'ip'      => fraudhosting_hash('203.0.113.4'),
]);

$ch = curl_init('https://api.fraud.hosting/api/');
curl_setopt_array($ch, [
  CURLOPT_POST           => true,
  CURLOPT_POSTFIELDS     => $payload,
  CURLOPT_HTTPHEADER     => ['Content-Type: application/x-www-form-urlencoded'],
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT        => 10,
]);

$response = curl_exec($ch);
if ($response === false) {
  throw new RuntimeException('cURL error: ' . curl_error($ch));
}
curl_close($ch);

$segments = explode('-', trim(strip_tags($response)));
if (count($segments) !== 4) {
  throw new RuntimeException('Unexpected API response: ' . $response);
}

[$points, $reported, $reliability, $link] = $segments;
import requests

payload = {
  '_api': api_key,
  '_action': 'query',
  'email': fraudhosting_hash('client@example.com'),
  'ip': fraudhosting_hash('203.0.113.4'),
}

resp = requests.post('https://api.fraud.hosting/api/', data=payload)
resp.raise_for_status()

parts = resp.text.strip().split('-')
if len(parts) != 4:
  raise RuntimeError(f"Unexpected response: {resp.text}")

points, reported, reliability, link = parts
#include <curl/curl.h>
#include <map>
#include <stdexcept>
#include <sstream>
#include <string>
#include <vector>

size_t write_cb(void* contents, size_t size, size_t nmemb, void* userp)
{
  std::string* s = static_cast<std::string*>(userp);
  s->append(static_cast<char*>(contents), size * nmemb);
  return size * nmemb;
}

std::string url_encode(CURL* curl, const std::string& value)
{
  char* encoded = curl_easy_escape(curl, value.c_str(), value.length());
  std::string result(encoded);
  curl_free(encoded);
  return result;
}

struct QueryResult {
  std::string points;
  std::string reported;
  std::string reliability;
  std::string link;
};

QueryResult query_client(const std::string& apiKey,
                       const std::map<std::string, std::string>& hashedData)
{
  CURL* curl = curl_easy_init();
  if (!curl) throw std::runtime_error("curl init failed");

  std::ostringstream body;
  body << "_api=" << url_encode(curl, apiKey)
       << "&_action=query";

  for (const auto& kv : hashedData) {
      body << "&" << kv.first << "=" << url_encode(curl, kv.second);
  }

  std::string response;
  curl_easy_setopt(curl, CURLOPT_URL, "https://api.fraud.hosting/api/");
  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.str().c_str());
  curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.str().size());
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

  CURLcode res = curl_easy_perform(curl);
  curl_easy_cleanup(curl);
  if (res != CURLE_OK) throw std::runtime_error("query failed");

  std::stringstream ss(response);
  std::string segment;
  std::vector<std::string> parts;
  while (std::getline(ss, segment, '-')) {
      parts.push_back(segment);
  }

  if (parts.size() != 4) {
      throw std::runtime_error("unexpected response: " + response);
  }

  return {parts[0], parts[1], parts[2], parts[3]};
}
package query

import (
	"errors"
	"io"
	"net/http"
	"net/url"
	"strings"
)

type Result struct {
	Points      string
	Reported    string
	Reliability string
	Link        string
}

func Query(apiKey string, hashedData map[string]string) (Result, error) {
	form := url.Values{
		"_api":    {apiKey},
		"_action": {"query"},
	}
	for k, v := range hashedData {
		form.Set(k, v)
	}

	resp, err := http.Post(
		"https://api.fraud.hosting/api/",
		"application/x-www-form-urlencoded",
		strings.NewReader(form.Encode()),
	)
	if err != nil {
		return Result{}, err
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	parts := strings.Split(strings.TrimSpace(string(body)), "-")
	if len(parts) != 4 {
		return Result{}, errors.New("unexpected response: " + string(body))
	}

	return Result{
		Points:      parts[0],
		Reported:    parts[1],
		Reliability: parts[2],
		Link:        parts[3],
	}, nil
}

Handling Errors

  • Response includes HTML or fewer than four segments → log and escalate. The upstream service occasionally returns placeholders during maintenance.
  • Network errors should be retried with exponential backoff, but avoid spamming—rate limits apply.

Showing Results to Users

Provide context for each value:

  • Use thresholds (e.g., highlight when Points >= 50 or Reported > 0).
  • Present the link as a button so operators can review narrative details.
  • If all values are zero, inform users that no matches were found but retain the link (FraudHosting may still return additional metadata on the details page).