Skip to content
noadmin

API

Check invite links from your own site

Bot lists, dashboards and CI jobs can use the NoAdmin API to find out what an invite link asks for. It is free, needs no key, and stores nothing.

Endpoints

GET/api/v1/analyze?input=Analyze one invite link or permission value.
POST/api/v1/analyzeSend {"input": "..."} for one, or {"inputs": [...]} for up to 50.
GET/api/v1/permissionsEvery Discord permission with its bit, value and risk level.
GET/api/v1/openapi.jsonOpenAPI 3.1 spec for generating a client.
GET/api/badge?invite=An SVG badge for a README or listing page.

Every endpoint allows cross-origin requests, so you can call it from a browser. GET responses are cached for an hour.

Blocking Administrator on a bot list

Run the check when a bot is submitted and when its invite link changes. If administrator is true, reject the submission and link the developer to report_url, which shows what the bot asked for and what to request instead.

TypeScript
const res = await fetch("https://noadmin.info/api/v1/analyze", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ input: bot.invite }),
});
const report = await res.json();

if (report.valid && report.administrator) {
  throw new Error(
    `This invite requests Administrator. See ${report.report_url}`,
  );
}
Go
var report struct {
	Valid         bool   `json:"valid"`
	Administrator bool   `json:"administrator"`
	ReportURL     string `json:"report_url"`
}

q := url.Values{"input": {invite}}
resp, err := http.Get("https://noadmin.info/api/v1/analyze?" + q.Encode())
if err != nil {
	return err
}
defer resp.Body.Close()
if err := json.NewDecoder(resp.Body).Decode(&report); err != nil {
	return err
}
if report.Valid && report.Administrator {
	return fmt.Errorf("invite requests Administrator, see %s", report.ReportURL)
}
curl
curl "https://noadmin.info/api/v1/analyze?input=https%3A%2F%2Fdiscord.com%2Foauth2%2Fauthorize%3Fclient_id%3D1234567890123456789%26permissions%3D8%26scope%3Dbot"

Response fields

validFalse when the input is not a permission number or a discord.com invite link. The error field says why.
administratorTrue when the invite requests Administrator. Check this field to block admin invites.
verdictnone, minimal, reasonable, broad, excessive or administrator. Use it for softer warnings.
permissionsThe permission integer as a string. It can be larger than a JavaScript number can hold exactly.
grantedEach requested permission with its risk and a link to its reference page.
report_urlA page that explains the result. Link to it from your rejection message.
Example response
{
  "input": "https://discord.com/oauth2/authorize?client_id=1234567890123456789&permissions=8&scope=bot",
  "valid": true,
  "source": "url",
  "client_id": "1234567890123456789",
  "scopes": [
    "bot"
  ],
  "permissions": "8",
  "permissions_hex": "0x8",
  "administrator": true,
  "verdict": "administrator",
  "verdict_label": "Administrator",
  "summary": "Full, unrestricted control of every server this bot joins.",
  "score": 0,
  "counts": {
    "low": 0,
    "medium": 0,
    "high": 0,
    "critical": 1
  },
  "granted": [
    {
      "key": "ADMINISTRATOR",
      "name": "Administrator",
      "bit": 3,
      "value": "8",
      "risk": "critical",
      "requires_2fa": true,
      "url": "https://noadmin.info/permissions/administrator"
    }
  ],
  "unknown_bits": [],
  "findings": [
    {
      "level": "critical",
      "title": "Requests Administrator",
      "body": "Administrator overrides every other permission and ignores all channel restrictions. Remove it and keep only what the bot uses."
    }
  ],
  "closest_example": null,
  "report_url": "https://noadmin.info/analyze?invite=https%3A%2F%2Fdiscord.com%2Foauth2%2Fauthorize%3Fclient_id%3D1234567890123456789%26permissions%3D8%26scope%3Dbot",
  "badge_url": "https://noadmin.info/api/badge?invite=https%3A%2F%2Fdiscord.com%2Foauth2%2Fauthorize%3Fclient_id%3D1234567890123456789%26permissions%3D8%26scope%3Dbot"
}

Checking without the API

If you only need the Administrator check, you can do it yourself with no network call. Administrator is bit 3, value 8. Use BigInt or a 64-bit integer, because permission values do not fit in a JavaScript number. The bitfield guide explains why.

TypeScript
const ADMINISTRATOR = BigInt(8);

function requestsAdmin(invite: string): boolean {
  const url = new URL(invite);
  const perms = url.searchParams.get("permissions");
  return perms !== null && /^\d+$/.test(perms)
    && (BigInt(perms) & ADMINISTRATOR) === ADMINISTRATOR;
}

Custom invite links

Some bots use their own domain for invites, which redirects to Discord. The API can only read discord.com links, and returns valid: false for anything else. Decide whether your list accepts those links, or asks for the discord.com link directly.