Skip to content

Go

A hand-rolled Go client for the FedShield REST API. Uses stdlib net/http and encoding/json — no external dependencies. An official SDK is on the roadmap.

The whole integration in under 100 lines:

package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/google/uuid"
)
const apiBase = "https://api.fedshield.io"
type Client struct {
http *http.Client
apiKey string
}
func NewClient(apiKey string) *Client {
return &Client{
http: &http.Client{Timeout: 5 * time.Second},
apiKey: apiKey,
}
}
type TrustEvent struct {
SchemaVersion string `json:"schema_version"`
EventID string `json:"event_id"`
EventType string `json:"event_type"`
PeerID string `json:"peer_id"`
PlayerID string `json:"player_id"`
GameID string `json:"game_id"`
Severity float64 `json:"severity"`
Timestamp time.Time `json:"timestamp"`
}
type TrustScore struct {
PlayerID string `json:"player_id"`
Score float64 `json:"score"`
Confidence float64 `json:"confidence"`
Verdict string `json:"verdict"`
EventCount int `json:"event_count"`
}
func (c *Client) SubmitEvent(ctx context.Context, e TrustEvent) error {
body, _ := json.Marshal(e)
req, _ := http.NewRequestWithContext(ctx, "POST",
apiBase+"/api/v1/events", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Peer-API-Key", c.apiKey)
resp, err := c.http.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode >= 300 {
return fmt.Errorf("submit event: %s", resp.Status)
}
return nil
}
func (c *Client) GetTrustScore(ctx context.Context, playerID string) (*TrustScore, error) {
req, _ := http.NewRequestWithContext(ctx, "GET",
apiBase+"/api/v1/players/"+playerID+"/trust-score", nil)
resp, err := c.http.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var s TrustScore
if err := json.NewDecoder(resp.Body).Decode(&s); err != nil {
return nil, err
}
return &s, nil
}
func main() {
ctx := context.Background()
// Read your peer_id and api_key from your secrets store.
// Register your peer once via the dashboard at https://fedshield.io/app/peers.
client := NewClient(os.Getenv("FEDSHIELD_API_KEY"))
peerID := os.Getenv("FEDSHIELD_PEER_ID")
event := TrustEvent{
SchemaVersion: "1.0.0",
EventID: uuid.NewString(),
EventType: "report_cheating",
PeerID: peerID,
PlayerID: "player-alice-123",
GameID: "my-game",
Severity: 0.85,
Timestamp: time.Now().UTC(),
}
if err := client.SubmitEvent(ctx, event); err != nil {
log.Fatalf("submit: %v", err)
}
score, err := client.GetTrustScore(ctx, "player-alice-123")
if err != nil {
log.Fatalf("score: %v", err)
}
fmt.Printf("player score=%.1f verdict=%s confidence=%.2f\n",
score.Score, score.Verdict, score.Confidence)
}

The score is advisory. Your game decides what to do:

func decideMatchmakingPolicy(score *TrustScore) string {
if score.Confidence < 0.2 {
// Not enough history — treat as neutral.
return "ranked_allowed"
}
switch score.Verdict {
case "trusted", "neutral":
return "ranked_allowed"
case "suspicious":
return "ranked_locked_24h"
case "untrusted":
return "ranked_locked_permanent"
default:
return "ranked_allowed"
}
}

Set event_type on the TrustEvent struct to one of:

Event typeWhen to submit
report_cheatingPlayer caught cheating (aimbot, wallhack, macro)
report_toxicityChat / voice reported for abuse
report_spamRepeated no-value events (queue-dodging, AFK farming)
friendly_fireTeam-killing above the tolerance floor
session_anomalyImpossible movement, teleport, physics violations
matchmaking_fraudBoosting, smurfing, ranked manipulation
ban_appliedYour studio issued a ban (severity 1.0)
ban_liftedYour studio reversed a ban
commendationPositive signal — good sportsmanship, teaching new players

Register your peer once via the dashboard at https://fedshield.io/app/peers, copy the peer_id and api_key into your secrets store, then read them from env vars as in the example above.