Free & public · An Aristois service

Sign in with Minecraft.
No passwords involved.

Let players log in to your website with their Minecraft account. They prove ownership by joining a server, and you get a verified UUID and username from one HTTP call. No credentials or API keys, and you don't have to register.

Or join in Minecraft auth.aristois.net

How it works

A short-lived, single-use 6-digit code links a verified Minecraft account to your website.

  1. 1

    Player gets a code

    They join auth.aristois.net with any Minecraft version and get kicked with a code.

  2. 2

    Code reaches your site

    The player types the code into your login form.

  3. 3

    You redeem it

    Your backend calls GET /token/{code} and receives the player's UUID and username. The code is invalidated immediately.

5 mincode lifetime
1×single use
0credentials shared
AllMinecraft versions

API

Base URL https://auth.aristois.net. All responses are JSON. Call it from your backend: no CORS headers are sent.

GET /token/{code} Redeem and invalidate a code

Query parameters

NameDescription
origin optional Your site's origin, e.g. https://example.com. Rejects codes that were issued through the redirect flow for a different site. Recommended for redirect logins.

Response 200 OK

{
  "status": "success",
  "message": "Token has been invalidated",
  "uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5",
  "username": "Notch"
}

Status codes

StatusMeaning
200Valid code. uuid is lower-case with dashes.
403Unknown, expired or already used code, or origin mismatch.
404The code is not exactly 6 digits.
429Rate limited. Honour the Retry-After header.
502/503Temporarily unavailable. Retry later.

Examples

Copy-paste integrations. Expand one to see the code.

TS Redeem a code TypeScript · Node 18+, Deno, Bun
interface TokenSuccess {
  status: 'success';
  message: string;
  uuid: string;     // lower-case, with dashes
  username: string;
}

interface TokenFailure {
  status: 'fail';
  message: string;
}

export interface MinecraftUser {
  uuid: string;
  username: string;
}

const BASE_URL = 'https://auth.aristois.net';

/** Redeems a single-use code. Returns null if it is invalid, expired or already used. */
export async function redeem(code: string, origin?: string): Promise<MinecraftUser | null> {
  if (!/^\d{6}$/.test(code)) return null;

  const url = new URL(`/token/${code}`, BASE_URL);
  if (origin) url.searchParams.set('origin', origin);

  const response = await fetch(url, { signal: AbortSignal.timeout(10_000) });
  if (response.status === 403 || response.status === 404) return null;
  if (!response.ok) throw new Error(`authentify returned HTTP ${response.status}`);

  const data = (await response.json()) as TokenSuccess | TokenFailure;
  return data.status === 'success'
    ? { uuid: data.uuid, username: data.username }
    : null;
}

// Usage: a player typed the code from the Minecraft kick screen into your form
const user = await redeem('123456');
if (user) console.log(`Logged in as ${user.username} (${user.uuid})`);
Java Redeem a code Java 17+ · java.net.http + Jackson
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Optional;
import java.util.UUID;

public final class Authentify {

    @JsonIgnoreProperties(ignoreUnknown = true)
    public record TokenResponse(String status, String message, String uuid, String username) {}

    public record MinecraftUser(UUID uuid, String username) {}

    private static final String BASE_URL = "https://auth.aristois.net";
    private static final ObjectMapper JSON = new ObjectMapper();
    private static final HttpClient HTTP = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(5))
            .build();

    private Authentify() {}

    /**
     * Redeems a single-use code.
     *
     * @param origin your site's origin, e.g. "https://example.com", or null
     * @return the player, or empty if the code is invalid, expired or already used
     */
    public static Optional<MinecraftUser> redeem(String code, String origin)
            throws IOException, InterruptedException {
        if (code == null || !code.matches("\\d{6}")) {
            return Optional.empty();
        }

        String url = BASE_URL + "/token/" + code;
        if (origin != null) {
            url += "?origin=" + URLEncoder.encode(origin, StandardCharsets.UTF_8);
        }

        HttpRequest request = HttpRequest.newBuilder(URI.create(url))
                .timeout(Duration.ofSeconds(10))
                .header("Accept", "application/json")
                .GET()
                .build();
        HttpResponse<String> response = HTTP.send(request, HttpResponse.BodyHandlers.ofString());

        int status = response.statusCode();
        if (status == 403 || status == 404) {
            return Optional.empty();
        }
        if (status != 200) {
            throw new IOException("authentify returned HTTP " + status);
        }

        TokenResponse body = JSON.readValue(response.body(), TokenResponse.class);
        if (!"success".equals(body.status())) {
            return Optional.empty();
        }
        return Optional.of(new MinecraftUser(UUID.fromString(body.uuid()), body.username()));
    }
}

// Usage
Authentify.redeem("123456", null).ifPresentOrElse(
        user -> System.out.println("Logged in as " + user.username() + " (" + user.uuid() + ")"),
        () -> System.out.println("Invalid or expired code"));