If you’ve ever wondered “is this signed-response stuff actually real or marketing?”, the curl examples below are your answer. The Node verification snippet at the bottom proves a real Ed25519 signature against the public key on this very page - no account, no SDK, no trust. The credentials hit a public sandbox app on the liveDocumentation Index
Fetch the complete documentation index at: https://docs.authforge.cc/llms.txt
Use this file to discover all available pages before exploring further.
auth.authforge.cc endpoint. Every request goes through the production code path - real Ed25519 signing, real nonce replay protection, real rate limits - and returns a payload that’s byte-for-byte indistinguishable from one a paying customer would get. The only difference is that this app’s traffic doesn’t get billed.
Demo credentials
| Field | Value |
|---|---|
| Application ID | 789ffbc6-555c-4a3c-8e9b-89be6f865195 |
| Application secret | demo-key-1a73-471e-ad08-8bd159b7e69c |
| Application Ed25519 public key | XRvq8r6PnKqJuNNBrNezhwPmZs887l1Fu4U/WGPz8Wc= |
| Demo license key | HE6H-S2V5-PKMW-WDVD |
1. Validate
This is the first call every SDK makes. It binds your HWID (or in this case doesn’t, since the key is unlimited-seat), debits one credit (skipped on the demo), and returns a signed session token plus the entitlements you’d want to render in your UI.| Field | Type | Notes |
|---|---|---|
status | string | "success" on the happy path; "failed" with an error code otherwise. |
payload | string | Base64-encoded JSON. Decode it to read the entitlements (see fields below). |
signature | string | Base64 Ed25519 signature, always 88 chars. Verify it against the app’s public key before trusting payload. |
keyId | string | Identifier for the signing key. Useful when rotating keys: clients can pin multiple trusted keys and use keyId to pick the right verifier. |
payload you’ll see fields like sessionToken, expiresIn, licenseExpiresAt, unlimitedHwidSlots: true, and any application/license variables set on the app. The full field list is in Concepts → Signed payload fields.
We deliberately don’t print a fake payload/signature example here - hand-crafted strings can’t actually be verified, so they’d just be lying decoration. Run the curl above and you’ll have a real one to feed into the Node snippet below.
2. Heartbeat
Aftervalidate, your SDK keeps the session alive by calling /auth/heartbeat periodically with the sessionToken from the previous response. Heartbeats refresh the token and are how the server delivers instant revocations to running clients.
{ status, payload, signature, keyId }. The new payload carries a fresh sessionToken and expiresIn.
3. Self-ban
Lets a client self-report cheating / tampering / EULA violations and ask the server to revoke or blacklist itself. Useful for anti-tamper integrations - the server is the source of truth and other SDKs on this license stop working immediately.The demo app neutralizes selfban. This call below is intentionally a no-op: it exists so you can see the request and response shape, the auth + rate-limit pipeline, and confirm that the endpoint accepts your payload. It does not revoke the demo license or blacklist anything, no matter what flags you send. If it did, the first reviewer would lock everyone else out of the demo. In your own app, the same handler with the same flags does revoke the license and persist the blacklist - that’s the whole point of the endpoint.
performed object is the server’s honest report of what it actually did - on the demo app, it’s always all-false. In production it reflects the request flags (defaulting to true post-session, false for revokeLicense pre-session).
Verify the signed payload (Node)
This is the part that matters. The whole point of “signed validation” is that you can verify the response server-side without trusting the network or any TLS-terminating intermediary. Drop this into a.mjs file and run it after the validate call above:
verify(...) returns true, you’ve confirmed end-to-end that:
- The
payloadyou received was signed by the private key paired with the public key in this docs page. - Nobody between AuthForge and your machine modified a single byte of the JSON.
- The entitlement fields inside
payload(license expiry, variables,unlimitedHwidSlots, etc.) can be trusted as offline-verifiable claims.
Now make your own keys
You just verified a real Ed25519 signature against a real production endpoint. The exact same code, with your own
appId / appSecret / public key, is your entire integration. Sign up for free, get starter credits, and ship - no credit card, takes about a minute.Limits
The demo has a hard guardrail at every layer. Reviewers running the curl examples in parallel during a traffic spike will sometimes hit one - that’s the design, not a bug.| Limit | Value | Error returned |
|---|---|---|
| Per-IP rate (validate) | 20 req/min | rate_limited |
| Per-IP rate (heartbeat) | 20 req/min | rate_limited |
| Per-IP rate (selfban) | 20 req/min | rate_limited |
| Per-license rate (validate) | 60 req/min | rate_limited |
| Per-license rate (selfban) | 30 req/min | rate_limited |
| Per-app daily ceiling | 50,000 req/day | demo_quota_exceeded |
rate_limited resets continuously (token-bucket refill); demo_quota_exceeded resets at 00:00 UTC. Both come back with HTTP 429. Your own apps have looser per-IP / per-license limits and no daily ceiling - they’re billed per request instead.
Ready for the real thing?
Create an account - it’s free, comes with starter credits, and gets you your ownappId/appSecret plus unlimited license generation. The exact same code you wrote against the demo will work against your own credentials with a one-line swap.