Fake signups

Know which new accounts are people

Send the registration form as it arrives: the name, the email address and the bio. ToxicFilter checks each field with its own rules and gives one answer, with the reason for every finding and the facts you need to decide yourself, such as the address's canonical form and whether its domain can receive mail.

How it works

  1. Send the form as it is

    One call to POST /v1/signup with the name, the email address and the bio, any of them optional, plus the languages your site is in. No model reads it by default, so a signup costs one credit.

  2. Each field has its own rules

    The address is checked against a list of throwaway providers, email-to-SMS gateways and the alias tricks of Gmail. The name is checked only for things that are not a name. The bio goes through the same text checks as a comment.

  3. One answer for the person

    Every finding from the three fields comes back together, each with its sentence: a throwaway address next to a keyboard-mashed name next to a bio of links reads as what it is.

  4. The facts stay yours

    The answer carries the address in its canonical form and, when it was looked up, whether the domain can receive mail. Matching that against the accounts you already have is your call.

See it decide

  1. 01 A bio that is only links
  2. 02 A bio that sends people elsewhere
  3. 03 A bio in another alphabet
  4. 04 A real person's bio

A bio that is only links POST /v1/signup (bio)

https://bit.ly/cheap-pills best prices, cheap-deals.example.com and casino-bonus.example.net

review 11 ms
  • Opens with a link. People answering a question write first and link after.
  • 3 links in about 13 words: mostly links, barely a message.
  • Uses a link shortener, which hides where the link goes.

It opens with a link, carries three in thirteen words and hides one behind a shortener. Held under the shipped lines; the dating template, with spam at 0.65, refuses it.

The answer, abridged
{
  "decision": "review",
  "flagged": [
    "spam"
  ],
  "scores": {
    "spam": 0.75
  },
  "signals": [
    {
      "category": "spam",
      "score": 0.75,
      "reason": "Opens with a link. People answering a question write first and link after.",
      "evidence": [
        "https://bit.ly/cheap-pills best prices, cheap-deals.example.com and casino-bonus"
      ]
    },
    {
      "category": "spam",
      "score": 0.75,
      "reason": "3 links in about 13 words: mostly links, barely a message.",
      "evidence": [
        "https://bit.ly/cheap-pills",
        "example.com",
        "example.net"
      ]
    },
    {
      "category": "spam",
      "score": 0.7,
      "reason": "Uses a link shortener, which hides where the link goes.",
      "evidence": [
        "https://bit.ly/cheap-pills"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 11
}

A bio that sends people elsewhere POST /v1/signup (bio)

Crypto trader. DM me on Telegram @fastprofits for daily signals, link: bit.ly/x9k2

review 8 ms
  • Uses a link shortener, which hides where the link goes.
  • Points the reader to a private chat app, which is where a deal leaves the platform.

A chat handle and a shortened link: the profile exists to move people somewhere else. Held for review, not refused.

The answer, abridged
{
  "decision": "review",
  "flagged": [
    "spam"
  ],
  "scores": {
    "spam": 0.7
  },
  "topics": {
    "crypto": 0.328
  },
  "signals": [
    {
      "category": "spam",
      "score": 0.7,
      "reason": "Uses a link shortener, which hides where the link goes.",
      "evidence": [
        "bit.ly/x9k2"
      ]
    },
    {
      "category": "spam",
      "score": 0.65,
      "reason": "Points the reader to a private chat app, which is where a deal leaves the platform.",
      "evidence": [
        "Telegram @fastprofits"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 8
}

A bio in another alphabet POST /v1/signup (bio)

Привет, я продаю аккаунты и подписчиков, пишите в личку, быстро и дешево

review 10 ms
  • Written mostly in cyrillic (58 letters, 100% of the text) on a site set to en.
  • Reads as ru on a site set to en, and by a clear margin (0.41).

Written entirely in Cyrillic on a site that said it is in English. Short and with no link, it could be a reader writing in their language, so it is held for a person rather than refused; a long wall or one carrying a link is refused. Under fifteen foreign letters, a name or a quoted word, it is left alone.

The answer, abridged
{
  "decision": "review",
  "flagged": [
    "off_topic",
    "spam"
  ],
  "scores": {
    "off_topic": 0.9,
    "spam": 0.75
  },
  "signals": [
    {
      "category": "spam",
      "score": 0.75,
      "reason": "Written mostly in cyrillic (58 letters, 100% of the text) on a site set to en.",
      "evidence": [
        "я продаю аккаунты и подписчиков"
      ]
    },
    {
      "category": "off_topic",
      "score": 0.9,
      "reason": "Reads as ru on a site set to en, and by a clear margin (0.41).",
      "evidence": [
        "Привет, я продаю аккаунты и подписчиков, пишите в личку, быстро и дешево"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 10
}

A real person's bio POST /v1/signup (bio)

Gardener in Valencia. I mostly come here for the bird photos and the seed swaps.

allow 8 ms

Most bios look like this. Settled by the free checks in about a millisecond.

The answer, abridged
{
  "decision": "allow",
  "flagged": [],
  "signals": [],
  "model": {
    "read": false
  },
  "took_ms": 8
}

See it decide

A bio that is only links POST /v1/signup (bio)

https://bit.ly/cheap-pills best prices, cheap-deals.example.com and casino-bonus.example.net

review 11 ms
  • Opens with a link. People answering a question write first and link after.
  • 3 links in about 13 words: mostly links, barely a message.
  • Uses a link shortener, which hides where the link goes.

It opens with a link, carries three in thirteen words and hides one behind a shortener. Held under the shipped lines; the dating template, with spam at 0.65, refuses it.

The answer, abridged
{
  "decision": "review",
  "flagged": [
    "spam"
  ],
  "scores": {
    "spam": 0.75
  },
  "signals": [
    {
      "category": "spam",
      "score": 0.75,
      "reason": "Opens with a link. People answering a question write first and link after.",
      "evidence": [
        "https://bit.ly/cheap-pills best prices, cheap-deals.example.com and casino-bonus"
      ]
    },
    {
      "category": "spam",
      "score": 0.75,
      "reason": "3 links in about 13 words: mostly links, barely a message.",
      "evidence": [
        "https://bit.ly/cheap-pills",
        "example.com",
        "example.net"
      ]
    },
    {
      "category": "spam",
      "score": 0.7,
      "reason": "Uses a link shortener, which hides where the link goes.",
      "evidence": [
        "https://bit.ly/cheap-pills"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 11
}

A bio that sends people elsewhere POST /v1/signup (bio)

Crypto trader. DM me on Telegram @fastprofits for daily signals, link: bit.ly/x9k2

review 8 ms
  • Uses a link shortener, which hides where the link goes.
  • Points the reader to a private chat app, which is where a deal leaves the platform.

A chat handle and a shortened link: the profile exists to move people somewhere else. Held for review, not refused.

The answer, abridged
{
  "decision": "review",
  "flagged": [
    "spam"
  ],
  "scores": {
    "spam": 0.7
  },
  "topics": {
    "crypto": 0.328
  },
  "signals": [
    {
      "category": "spam",
      "score": 0.7,
      "reason": "Uses a link shortener, which hides where the link goes.",
      "evidence": [
        "bit.ly/x9k2"
      ]
    },
    {
      "category": "spam",
      "score": 0.65,
      "reason": "Points the reader to a private chat app, which is where a deal leaves the platform.",
      "evidence": [
        "Telegram @fastprofits"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 8
}

A bio in another alphabet POST /v1/signup (bio)

Привет, я продаю аккаунты и подписчиков, пишите в личку, быстро и дешево

review 10 ms
  • Written mostly in cyrillic (58 letters, 100% of the text) on a site set to en.
  • Reads as ru on a site set to en, and by a clear margin (0.41).

Written entirely in Cyrillic on a site that said it is in English. Short and with no link, it could be a reader writing in their language, so it is held for a person rather than refused; a long wall or one carrying a link is refused. Under fifteen foreign letters, a name or a quoted word, it is left alone.

The answer, abridged
{
  "decision": "review",
  "flagged": [
    "off_topic",
    "spam"
  ],
  "scores": {
    "off_topic": 0.9,
    "spam": 0.75
  },
  "signals": [
    {
      "category": "spam",
      "score": 0.75,
      "reason": "Written mostly in cyrillic (58 letters, 100% of the text) on a site set to en.",
      "evidence": [
        "я продаю аккаунты и подписчиков"
      ]
    },
    {
      "category": "off_topic",
      "score": 0.9,
      "reason": "Reads as ru on a site set to en, and by a clear margin (0.41).",
      "evidence": [
        "Привет, я продаю аккаунты и подписчиков, пишите в личку, быстро и дешево"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 10
}

A real person's bio POST /v1/signup (bio)

Gardener in Valencia. I mostly come here for the bird photos and the seed swaps.

allow 8 ms

Most bios look like this. Settled by the free checks in about a millisecond.

The answer, abridged
{
  "decision": "allow",
  "flagged": [],
  "signals": [],
  "model": {
    "read": false
  },
  "took_ms": 8
}

Fake signups, field by field

What each part of a registration form gives away, and what ToxicFilter checks in it.

How to detect fake signups

A bot filling your registration form leaves traces in every field, and each one alone is weak: plenty of honest people use a plus tag, a short name or a link to their own site. Checking the fields one at a time throws away the fact that they arrived together. POST /v1/signup takes the name, the address and the bio in one call, judges each with its own rules and returns one decision with every finding beside its reason.

Blocking disposable email addresses

Throwaway services exist so an address can pass a confirmation email and disappear. ToxicFilter keeps a list of them and refuses addresses on it. The list is not published, and it is not the only check: a domain that cannot receive mail is reported whether it is on a list or not.

Gmail dots and plus aliases: one inbox, many accounts

To a unique column, name@gmail.com, n.a.m.e@gmail.com and name+2@gmail.com are three accounts. To Gmail they are one inbox. Every answer for an address carries its canonical form, so you can look it up among your users before creating a second account for the same person. A Gmail alias is also reported on spam at 0.45, just under the shipped review line, so lowering spam to 0.45 in your policy is what holds it.

Checking an email domain can receive mail

A domain with no mail server cannot receive the confirmation you are about to send. ToxicFilter looks for an MX record, or an A record, since small domains often receive mail there, and caches the answer for a day. It catches the typo and the invented domain, which are most bad addresses that are not on any list.

Names that are not names

Rejecting a real name tells someone their name is not a name, so the name check is narrow on purpose. It looks for placeholders, keyboard runs, strings of consonants and links typed into the name field. Everything else passes, whatever the alphabet or the length.

The bio is checked like any comment: links at the start, many links in few words, shorteners, chat handles, phone numbers and email addresses. Tell it which languages your site is in and a bio written in another alphabet, or clearly in another language, is reported too.

How the work is split

The instant checks settle the clear cases in about a millisecond, the model reads what depends on context, and your rules and your people have the last word.

  • Your users table stays yours

    Every answer carries the canonical form of the address, so you can look it up among your own users before creating a second account for the same person. Nothing about the signup is kept beyond the verdict and a hash.

  • Two checks on every address

    A maintained list of throwaway providers, and a look at whether the domain can receive mail at all, remembered for a day. An address does not have to be on a list to be reported.

  • Real names pass

    No minimum length, no alphabet rule, no dictionary: Ng, Li or a name in any script passes. It looks for placeholders, keyboard runs, Latin letters with no vowel and links, and a placeholder or a mashed name alone is held for review, never refused.

Frequently asked questions

How do I detect fake signups?

Send the whole registration to POST /v1/signup: name, email and bio together, so the answer has every finding about the person in one place. Each field can also be checked on its own with POST /v1/email and POST /v1/name. None of them call a model by default, and /v1/email never does: an address is on a list or it is not.

Can I block disposable email addresses?

Yes. An address from a throwaway provider scores 0.9 on spam, which is a block under the shipped lines, with the reason "the address will not exist in an hour". The list is maintained with the install and is not published, because a published list is a map of what gets through.

Does it catch Gmail dot and plus aliases?

Gmail ignores dots and anything after a plus, so n.a.m.e+1@gmail.com and name@gmail.com are one inbox. That alias scores 0.45 on spam, just under the shipped review line of 0.50, so it is reported without holding the signup; a policy with spam at 0.45 holds it. The answer gives the canonical form in facts.email.canonical. Dots are only removed for Google: elsewhere they make two different people. Plus tags are removed everywhere in the canonical form, and on other providers they score lower still (0.40), because careful people use them too.

Does it check that the domain can receive email?

It looks for an MX or an A record and remembers the answer for a day. A domain with neither scores 0.75 on spam, held for review. The answer says facts.email.mx true or false, and leaves it out when it did not look, for instance when DNS did not answer: not looking is never reported as no.

What is an email-to-SMS gateway, and why refuse it?

An address like a phone number at a carrier's domain, where mail arrives as a text message on that phone. Nobody signs up with one. A bot types it into a form that emails a code, and the form becomes a free SMS sender aimed at a stranger. It scores 0.85 on spam and is refused.

Will it reject real names that look unusual?

It is built not to. There is no minimum length beyond one character, no alphabet rule, no need for two words and no dictionary, so Ng, Li or a name in any script passes. What it catches is a placeholder such as test or asdf, a run of adjacent keys, six or more Latin letters with no vowel, and a link or an address in the name field, which is refused.

Try it on your own traffic

2,000 credits a month on the free plan, no card. Enough to send a week of your own content and see what it says about it.