All pages

POST /api/v1/signup

Check a signup

Name, email and bio judged together, before the account exists.

Name, email and bio judged together, before the account exists. One call instead of three, and one verdict for the registration as a whole.

Parameters

FieldTypeRequired
namestringat least one of the threeUp to 200 characters.
emailstringUp to 320 characters.
biostringUp to 2,000 characters.
localesstring[]noYour site's languages, up to ten.
aibooleanno Default false. Can be turned on, because a bio is writing.
referencestringno Your own id for the thing being judged, up to 120 characters. Never parsed, stored and handed back, so a verdict is findable later by the name you already use for it.
policystringno Which of your policies to judge under. Absent means the project's policy, then your default; an account with none gets the shipped thresholds.
projectstringno Which of your projects the verdict is filed under. Absent means your default project.
actorstringno Your own id for whoever wrote it. Filed with the verdict, and used to move the line when a policy asks for reputation.

ai defaults to false here. Registration is a hot path that fires on traffic you have not qualified yet, including bot floods, and the cheap detectors catch what a signup usually is. Pass ai: true deliberately when the bio matters to you.

Where every endpoint stands on that default, since it is the one thing that decides whether a call costs one credit or a model reading on top:

Endpointai when you say nothing
/text, /prompt, /image, /conversationtrue. That is what those endpoints are for.
/signupfalse, and you can turn it on.
/name, /email, /urlfalse, and it cannot be turned on: "ai": true is a 422 ai_unavailable. No model reads a name, an address or a link.

Sending none of the three returns a 422 with nothing_to_check.

Request

curl https://toxicfilter.com/api/v1/signup \
  -H "Authorization: Bearer tf_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "SEO Expert",
    "email": "qx7f2k@mailinator.com",
    "bio": "Cheap backlinks, DM me. Visit www.example-spam.tld for rates.",
    "locales": ["en"]
  }'

Response

{
  "decision": "block",
  "flagged": ["spam"],
  "scores": { "spam": 0.88 },
  "signals": [
    {
      "category": "spam",
      "score": 0.88,
      "detector": "link_spam",
      "reason": "Promotional link and an offer of paid services in a profile bio.",
      "evidence": ["www.example-spam.tld"]
    },
    {
      "category": "spam",
      "score": 0.61,
      "detector": "contact_details",
      "reason": "Disposable mailbox provider.",
      "evidence": ["mailinator.com"]
    }
  ],
  "used_ai": false,
  "took_ms": 5,
  "credits": { "remaining": 4862, "renews_at": "2026-09-30T00:00:00+00:00" }
}

The three fields are judged as one registration, which is what makes this worth a separate endpoint: a throwaway address is weak evidence, a promotional bio is weak evidence, and the two together are not.