FairScale

Code Examples

Integration patterns for FairScale APIs in JavaScript, TypeScript, Python, and cURL

Code Examples

Integration patterns for both FairScale APIs — the Agent & Credit API (agent-api.fairscale.xyz) and the Human Score API (api.fairscale.xyz).

For use-case-specific examples (agents, DeFi, lending), see Solutions.

Quick Start

Score an agent with a fairkey:

curl "https://agent-api.fairscale.xyz/v1/score?wallet=WALLET_ADDRESS" \
  -H "fairkey: zpka_your_key_here"

Trust gate — allow or deny in one call:

curl "https://agent-api.fairscale.xyz/v1/trust-gate?wallet=WALLET_ADDRESS&min_score=60" \
  -H "fairkey: zpka_your_key_here"

Score with x402 (autonomous agent, no account needed):

import { wrapFetch } from "@dexterai/x402/client";

const x402Fetch = wrapFetch(fetch, {
  walletPrivateKey: process.env.SOLANA_PRIVATE_KEY,
});

const res = await x402Fetch(
  "https://agent-api.fairscale.xyz/v1/score?wallet=AGENT_WALLET"
);
const { score, tier, pillars } = await res.json();

Custom-weighted score for hiring:

curl "https://agent-api.fairscale.xyz/v1/score/ai?wallet=AGENT_WALLET&preset=hiring" \
  -H "fairkey: zpka_your_key_here"

Batch screen multiple agents:

curl -X POST "https://agent-api.fairscale.xyz/v1/score/batch" \
  -H "fairkey: zpka_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "wallets": ["AGENT_1", "AGENT_2", "AGENT_3"] }'

Credit assessment for lending:

curl "https://agent-api.fairscale.xyz/v1/credit?wallet=WALLET_ADDRESS&amount=5000" \
  -H "X-Api-Key: zpka_your_key_here"

Human Score API

The Human Score API returns a rich feature fingerprint for any Solana wallet — 15 on-chain signals, badges, actions, tier, and a humanity attestation.

Full wallet analysis

curl "https://api.fairscale.xyz/score?wallet=WALLET_ADDRESS" \
  -H "fairkey: zpka_your_key_here"
import { FairScale } from "@fairscale/sdk";

const client = new FairScale({ apiKey: process.env.FAIRSCALE_API_KEY });

const result = await client.human.getScore("WALLET_ADDRESS");

console.log(result.fairscore);       // 38.7
console.log(result.tier);            // "silver"
console.log(result.badges);          // [{ id: "lst_staker", label: "LST Staker", ... }, ...]
console.log(result.features.native_sol_percentile); // 96.73

Render a dashboard-style insight card

Derive the five pillars, the Humanity Index, and grouped feature categories without a second round-trip:

const score = await client.human.getScore(wallet);

const pillars   = client.insights.pillars(score);
const humanity  = client.insights.humanityIndex(score);
const fp        = client.insights.fingerprint(score);

return {
  headline: {
    score: score.fairscore,
    tier: score.tier,
    humanity: humanity.tier,   // "verified_human" | "likely_human" | "unverified"
  },
  pillars,                     // { economy, risk, activity, diversification, social }
  onchain: {
    portfolio:        fp.portfolio,           // SOL / majors / stables / LSTs (percentiles)
    capital_flow:     fp.capital_flow,        // net SOL 30d
    conviction:       fp.holding_conviction,  // median hold, conviction ratio
    tempo:            fp.activity_tempo,      // tx count, active days, gaps
    trading_behaviour: fp.trading_behaviour,  // timing variance, burst ratio
  },
  badges: score.badges,
  next_steps: score.actions,
};

Sybil filter — reject low-activity or bot-like wallets

async function passesSybilCheck(wallet: string) {
  const score = await client.human.getScore(wallet);
  const f = score.features;

  if (score.verified_human) return true;               // VeryAI-attested human → always pass
  if (score.fairscore < 40) return false;              // too low overall
  if (f.tx_count < 20) return false;                   // inactive wallet
  if (f.burst_ratio > 0.5) return false;               // bot-like clustering
  if (f.tempo_cv < 0.3) return false;                  // metronomic timing → bot
  if (f.platform_diversity < 2) return false;          // single-protocol farmer

  return true;
}

One-call full profile

const profile = await client.profile("WALLET");

profile.score;           // HumanScoreResponse
profile.pillars;         // { economy, risk, activity, diversification, social }
profile.humanity_index;  // { score, tier }
profile.fingerprint;     // Grouped feature categories

Python — features → pillars

import os, requests

FAIRSCALE_API_KEY = os.getenv("FAIRSCALE_API_KEY")

def get_human_score(wallet: str, twitter: str | None = None) -> dict:
    params = {"wallet": wallet}
    if twitter:
        params["twitter"] = twitter
    r = requests.get(
        "https://api.fairscale.xyz/score",
        params=params,
        headers={"fairkey": FAIRSCALE_API_KEY},
    )
    r.raise_for_status()
    return r.json()

score = get_human_score("WALLET_ADDRESS")
f = score["features"]

economy  = (f["major_percentile_score"] + f["stable_percentile_score"]
            + f["native_sol_percentile"] + f["lst_percentile_score"]) / 4
activity = (f["tx_count"] + f["active_days"]) / 2
risk_ok  = f["no_instant_dumps"] == 1 and f["conviction_ratio"] > 0.4

print(f"FairScore: {score['fairscore']}  Tier: {score['tier']}")
print(f"Economy pillar (avg percentile): {economy:.1f}")
print(f"Activity: {activity:.1f}  |  Risk OK: {risk_ok}")

Quick integer shortcuts

# Final blended score (0–1000 integer)
curl "https://api.fairscale.xyz/fairScore?wallet=WALLET" -H "fairkey: KEY"

# On-chain only (0–1000 integer)
curl "https://api.fairscale.xyz/walletScore?wallet=WALLET" -H "fairkey: KEY"

# Social only (0–1000 integer)
curl "https://api.fairscale.xyz/socialScore?wallet=WALLET&twitter=handle" -H "fairkey: KEY"

JavaScript / TypeScript

Basic score fetch

const FAIRSCALE_API_KEY = process.env.FAIRSCALE_API_KEY;

async function getAgentScore(wallet) {
  const res = await fetch(
    `https://agent-api.fairscale.xyz/v1/score?wallet=${wallet}`,
    { headers: { fairkey: FAIRSCALE_API_KEY } }
  );

  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

const result = await getAgentScore("WALLET_ADDRESS");
console.log("Score:", result.score);  // 67
console.log("Tier:", result.tier);    // "silver"

Trust gate middleware (Express.js)

import express from "express";

const app = express();

app.use("/api/protected", async (req, res, next) => {
  const agentWallet = req.headers["x-agent-wallet"] as string;
  if (!agentWallet) return res.status(401).json({ error: "missing_wallet" });

  const gateRes = await fetch(
    `https://agent-api.fairscale.xyz/v1/trust-gate?wallet=${agentWallet}&min_score=60`,
    { headers: { fairkey: process.env.FAIRSCALE_API_KEY! } }
  );

  const gate = await gateRes.json();
  if (!gate.allowed) {
    return res.status(403).json({ error: "trust_gate_failed", score: gate.score });
  }

  req.agentScore = gate.score;
  next();
});

Batch screening with results grouping

const wallets = ["WALLET_1", "WALLET_2", "WALLET_3", "WALLET_4"];

const res = await fetch("https://agent-api.fairscale.xyz/v1/score/batch", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    fairkey: process.env.FAIRSCALE_API_KEY!,
  },
  body: JSON.stringify({ wallets }),
});

const batch = await res.json();

const byTier = {
  gold:   batch.results.filter((r) => r.tier === "gold"),
  silver: batch.results.filter((r) => r.tier === "silver"),
  bronze: batch.results.filter((r) => r.tier === "bronze"),
  failed: batch.results.filter((r) => r.error),
};

React hook for agent scores

import { useState, useEffect } from "react";

export function useAgentScore(wallet: string | null) {
  const [data, setData]     = useState<AgentScoreResult | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError]   = useState<Error | null>(null);

  useEffect(() => {
    if (!wallet) return;

    setLoading(true);
    fetch(
      `https://agent-api.fairscale.xyz/v1/score?wallet=${wallet}`,
      { headers: { fairkey: process.env.NEXT_PUBLIC_FAIRSCALE_API_KEY ?? "" } }
    )
      .then((r) => { if (!r.ok) throw new Error("HTTP " + r.status); return r.json(); })
      .then(setData)
      .catch(setError)
      .finally(() => setLoading(false));
  }, [wallet]);

  return { data, loading, error };
}

Composable score with custom weights

async function scoreForContext(
  wallet: string,
  context: "defi" | "hiring" | "marketplace"
) {
  const presetMap = { defi: "defi", hiring: "hiring", marketplace: "trust_focused" };

  const res = await fetch(
    `https://agent-api.fairscale.xyz/v1/score/ai?wallet=${wallet}&preset=${presetMap[context]}`,
    { headers: { fairkey: process.env.FAIRSCALE_API_KEY! } }
  );

  return res.json();
}

Python

Basic score request

import os
import requests

FAIRSCALE_API_KEY = os.getenv("FAIRSCALE_API_KEY")
BASE_URL = "https://agent-api.fairscale.xyz"

def get_agent_score(wallet: str) -> dict:
    response = requests.get(
        f"{BASE_URL}/v1/score",
        params={"wallet": wallet},
        headers={"fairkey": FAIRSCALE_API_KEY},
    )
    response.raise_for_status()
    return response.json()

result = get_agent_score("WALLET_ADDRESS")
print(f"Score: {result['score']}")
print(f"Tier: {result['tier']}")

Batch screening

wallets = ["WALLET_1", "WALLET_2", "WALLET_3"]

response = requests.post(
    f"{BASE_URL}/v1/score/batch",
    json={"wallets": wallets},
    headers={"fairkey": FAIRSCALE_API_KEY, "Content-Type": "application/json"},
)
response.raise_for_status()
batch = response.json()

for r in batch["results"]:
    if "error" in r:
        print(f"{r['wallet']}: ERROR — {r['error']}")
    else:
        print(f"{r['wallet']}: {r['score']} ({r['tier']})")

Credit assessment

def get_credit_assessment(wallet: str, amount: int = 1000) -> dict:
    response = requests.get(
        f"{BASE_URL}/v1/credit",
        params={"wallet": wallet, "amount": amount},
        headers={"X-Api-Key": FAIRSCALE_API_KEY},
    )
    response.raise_for_status()
    return response.json()

credit = get_credit_assessment("WALLET_ADDRESS", amount=5000)
print(f"Credit score: {credit['credit_score']}")
print(f"Risk band: {credit['risk_band']}")
print(f"Max credit line: ${credit['underwriting']['lending_terms']['max_credit_line']}")

Node.js — Express API Route

const express = require("express");
const app = express();

app.get("/api/agent-score/:wallet", async (req, res) => {
  const { wallet } = req.params;

  try {
    const response = await fetch(
      `https://agent-api.fairscale.xyz/v1/score?wallet=${wallet}`,
      { headers: { fairkey: process.env.FAIRSCALE_API_KEY } }
    );

    if (!response.ok) {
      const err = await response.json();
      return res.status(response.status).json(err);
    }

    res.json(await response.json());
  } catch (error) {
    res.status(502).json({ error: "upstream_error" });
  }
});

app.listen(3000);

cURL Reference

# Single score
curl "https://agent-api.fairscale.xyz/v1/score?wallet=WALLET_ADDRESS" \
  -H "fairkey: zpka_your_key_here"

# Score with task context
curl "https://agent-api.fairscale.xyz/v1/score?wallet=WALLET_ADDRESS&task=defi_execution" \
  -H "fairkey: zpka_your_key_here"

# AI score — hiring preset
curl "https://agent-api.fairscale.xyz/v1/score/ai?wallet=WALLET_ADDRESS&preset=hiring" \
  -H "fairkey: zpka_your_key_here"

# AI score — custom weights
curl "https://agent-api.fairscale.xyz/v1/score/ai?wallet=WALLET_ADDRESS&verification=0.4&wallet_history=0.2&work_history=0.2&network_quality=0.1&peer_reputation=0.1" \
  -H "fairkey: zpka_your_key_here"

# Trust gate
curl "https://agent-api.fairscale.xyz/v1/trust-gate?wallet=WALLET_ADDRESS&min_score=60&require_verification=true" \
  -H "fairkey: zpka_your_key_here"

# Agent profile
curl "https://agent-api.fairscale.xyz/v1/agent?wallet=WALLET_ADDRESS" \
  -H "fairkey: zpka_your_key_here"

# Batch score
curl -X POST "https://agent-api.fairscale.xyz/v1/score/batch" \
  -H "fairkey: zpka_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "wallets": ["WALLET_1", "WALLET_2"] }'

# Directory — top agents
curl "https://agent-api.fairscale.xyz/v1/directory?sort=agent_fairscore&min_score=60&verified_only=true" \
  -H "fairkey: zpka_your_key_here"

# Leaderboard
curl "https://agent-api.fairscale.xyz/v1/leaderboard?metric=work_history&limit=10" \
  -H "fairkey: zpka_your_key_here"

# Score history
curl "https://agent-api.fairscale.xyz/v1/score-history?wallet=WALLET_ADDRESS" \
  -H "fairkey: zpka_your_key_here"

# Credit assessment
curl "https://agent-api.fairscale.xyz/v1/credit?wallet=WALLET_ADDRESS&amount=5000" \
  -H "X-Api-Key: zpka_your_key_here"

Best Practices

  • Store API keys in environment variables. Never hardcode.
  • Use trustGate for access-control checks — it's faster and purpose-built for allow/deny.
  • Cache scores locally when you're making the same check repeatedly; the API caches server-side for 15 minutes anyway.
  • Use scoreBatch for processing sets of wallets — avoids N individual requests.
  • For credit assessments, store the attestation.payload_hash alongside your loan record.