BlockID
For developers

Sign in with BlockID

Let people log in or sign up on your app using the BlockID they already hold — no new password, no OAuth provider. Your app asks the wallet for a signature; BlockID's own API verifies it and hands back the identity. Because verification happens on our server, not yours, this works from any backend language — you never need an Ethereum signature-verification library.

Live demo

How the flow works

  1. Your frontend calls POST /api/auth/challenge with the visitor's wallet address → gets back a one-time message to sign.
  2. The visitor's wallet signs that exact message (this is the one step that must happen in a browser).
  3. Your backend calls POST /api/auth/verify with { address, message, signature } and trusts the JSON it gets back.

1. Request a challenge

cURL — works identically from any language
curl -X POST https://YOUR-BLOCKID-DOMAIN/api/auth/challenge \
  -H "Content-Type: application/json" \
  -d '{"address": "0xYourUserAddress", "appName": "My App"}'

# 200 OK
{
  "address": "0x...",
  "nonce": "9f2c1a...",
  "message": "My App wants you to sign in with your BlockID.\n\nWallet: 0x...\nNonce: 9f2c1a...\nIssued At: 2026-09-05T12:00:00.000Z",
  "issuedAt": "2026-09-05T12:00:00.000Z",
  "expiresAt": 1757073600000
}

2. Have the wallet sign it, then verify

The signature happens client-side (e.g. personal_sign via window.ethereum, or our blockid-connect.js widget below). Once you have it, verification is a single call from whatever backend you run:

Python
import requests

resp = requests.post(
    "https://YOUR-BLOCKID-DOMAIN/api/auth/verify",
    json={"address": address, "message": message, "signature": signature},
)
data = resp.json()

if data.get("verified"):
    identity = data["identity"]
    # create your session using identity["identityContract"], etc.
else:
    print("BlockID sign-in failed:", data.get("error"))
Node / any JS backend
const resp = await fetch("https://YOUR-BLOCKID-DOMAIN/api/auth/verify", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ address, message, signature }),
});
const data = await resp.json();

if (data.verified) {
  // data.identity.fullName, data.identity.identityContract, ...
}

The same shape works from PHP (curl or Guzzle), Go (net/http), Ruby, Java — anything that can send JSON over HTTP and read a JSON response.

Or embed the widget

For a plain HTML site, skip building your own sign-in button — this drops one in and runs the same challenge/verify flow above for you.

HTML — no build step required
<script src="https://YOUR-BLOCKID-DOMAIN/blockid-connect.js"></script>
<div id="blockid-btn"></div>
<script>
  BlockIDConnect.init({
    apiBase: "https://YOUR-BLOCKID-DOMAIN",
    container: "#blockid-btn",
    appName: "My App",
    onSuccess: function (result) {
      // result.address, result.identity — already verified server-side
      // send result to YOUR backend to create the session
    },
    onError: function (message) {
      console.error(message);
    },
  });
</script>

Just checking an address?

If you already trust the address (no login claim involved) and just want its public identity data:

GET — no signature needed
GET https://YOUR-BLOCKID-DOMAIN/api/identity/0xYourUserAddress

200 OK
{
  "hasIdentity": true,
  "address": "0x...",
  "identityContract": "0x...",
  "owner": "0x...",
  "fullName": "Ada Lovelace",
  "details": "Mathematician.",
  "createdAt": 1730000000,
  "verified": true
}
BlockID · a self-owned identity contract for every walletPolygon · QuickNode · Blockscout