SOCI4L

Avalanche Guide

How the SOCI4L Reputation API Works

Four score dimensions instead of one number, batch scoring for a whole list, and signed responses you can verify without trusting us.

July 28, 2026 7 min read

Most onchain applications share one blind spot. An address tells you nothing about who is behind it. Balance and transaction count are public. Whether there is a real, established person there is not.

That gap is expensive. Airdrops go to bot fleets. Governance votes get counted one wallet at a time. Allowlists get farmed. Every one of those problems is the same missing answer, and none of them can be solved by looking harder at a hex string.

SOCI4L answers it over an API. This is how that API is put together and what it will and will not tell you.

Four numbers, not one

A single blended reputation score is easy to game and hard to use. Easy to game because there is only one target to push on. Hard to use because different applications are asking different questions and a blended number has already thrown away the distinction.

So the API returns four dimensions separately:

  • humanity is there a real person behind this address
  • social position in the follow graph
  • economic what it cost them to be here
  • activity transaction volume and freshness

An airdrop cares about humanity. A lending market cares about economic. A DAO cares about social. Each of them can read the dimension that matters and ignore the rest. A composite is also returned for anyone who wants one number anyway:

composite = 0.40 humanity
          + 0.25 social
          + 0.20 economic
          + 0.15 activity

Every input saturates. Wallet age reaches full credit at roughly two and a half years, transaction count runs on a logarithmic scale, and follower weight has diminishing returns. Ten thousand followers is not worth a hundred times what one hundred followers is worth, and the scoring reflects that rather than pretending otherwise.

What a call looks like

Every endpoint except the descriptor and the health probe takes anX-Api-Key header.

curl -H "X-Api-Key: s4_live_..." \
  https://soci4l.net/api/v1/score/0xYourAddress

The response carries the headline score, the four dimensions with a confidence value, and what the graph analysis found. Field names below are exact; the values are illustrative.

{
  "address": "0x...",
  "headline": {
    "score": 51,
    "tier": "established",
    "tierLabel": "Established"
  },
  "s4": {
    "humanity": 0.62,
    "social": 0.35,
    "economic": 0.28,
    "activity": 0.44,
    "composite": 0.47,
    "confidence": 0.71
  },
  "graph": {
    "analyzed": true,
    "flags": [],
    "socialDamping": 1
  },
  "verifiedHuman": 2,
  "fetchedAt": "2026-07-28T09:28:08.601Z"
}

The full endpoint surface is small on purpose:

GET  /api/v1/score/:address
GET  /api/v1/score/:address/signed
GET  /api/v1/score/:address/history
POST /api/v1/score/batch
GET  /api/v1/health

Scoring a whole list at once

The batch endpoint takes up to 50 addresses per call and costs one rate-limit unit per address. That turns an airdrop filter into a single request: send the list, read back scores and graph flags, and drop the addresses that only look like users.

curl -X POST -H "X-Api-Key: s4_live_..." \
  -H "Content-Type: application/json" \
  --data '{"addresses":["0x...","0x..."]}' \
  https://soci4l.net/api/v1/score/batch

Batch reads from cache rather than scoring on demand, so each result also tells you how fresh its signals are. An address that has never been scored comes back as signals: "none", and you warm it through the single-address endpoint first.

Signed scores, so you do not have to trust us

This is the part that matters most, and the part most reputation providers skip. A score is only useful if the person acting on it can tell it really came from the scorer and was not altered on the way.

The signed endpoint returns the score as an EIP-712 typed signature. You verify it on your own side, offline, without calling us a second time. A smart contract can check the same claim onchain against the attestation registry deployed on Avalanche mainnet.

GET /api/v1/score/:address/signed

{
  "domain": { "name": "SOCI4L Attestation", "version": "1", ... },
  "primaryType": "ScoreAttestation",
  "message": {
    "subject": "0x...",
    "score": "51",
    "humanity": "62",
    "verifiedHuman": true,
    "issuedAt": "...",
    "expiresAt": "...",
    "nonce": "..."
  },
  "signature": "0x...",
  "signer": "0x72C08d52998D08a312a9d9FFe3B131Cd6f32bB31"
}

That signer address is the public trust anchor, and it is published in the API descriptor so nobody has to take our word for which key is ours. If you want to see the mechanism work without writing code, paste any signed response into the verification page and it will check the signature in your browser.

The practical difference: a score that is merely returned is an opinion, and a score that is signed is evidence. Only the second kind can be handed to a contract or shown to a third party who has no reason to trust the source.

Saying when we are not sure

Every response carries a confidence value, and it exists because the honest answer is sometimes "we do not have enough to say".

When a signal cannot be measured for an address, we do not score it as zero. Scoring a missing signal as zero would quietly punish people for data we failed to collect. Instead its weight is redistributed across the signals we do have, and the confidence value comes down to say so.

The follow graph is also scanned for patterns that indicate a manufactured social position: reciprocal follow rings, follower counts that arrived inside a single day, follower masses made up of wallets with no history, and donations an address sent to itself. Anything found is returned ingraph.flags, the social dimension is damped, and confidence drops again.

Nothing there is hidden from the caller. The flags come back in the response because an integrator deciding whether to trust a score deserves to see why we hesitated.

What we promise about the schema

The v1 response schema is locked. Within v1, fields can be added, but never renamed, removed, or retyped. Anything that would break a caller ships as a separate v2 route instead.

That promise is enforced by a schema check that runs against production, not by good intentions. If you build against a field today, that field will still be there with the same name and the same type.

The scoring methodology is published for the same reason. A reputation score you cannot inspect is a score nobody should build on, and keeping the formula secret would not protect it anyway.

Getting a key

The free tier is 1,000 requests a day, with a burst limit of 60 requests per minute and 10 per minute on batch. Rate-limit headers come back on every call, and a burst rejection carries a Retry-After value in seconds so you know exactly how long to wait.

The descriptor at GET /api/v1 needs no key at all. It lists every endpoint, the current rate limits, and the attestation signer, so you can inspect the whole surface before deciding whether it is worth your time.

This is a live, versioned scoring API on the Avalanche C-Chain. The documentation is here, and scoring your first address takes about five minutes.