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
| Field | Type | Required | |
|---|---|---|---|
name | string | at least one of the three | Up to 200 characters. |
email | string | Up to 320 characters. | |
bio | string | Up to 2,000 characters. | |
locales | string[] | no | Your site's languages, up to ten. |
ai | boolean | no | Default false. Can be turned on, because a bio is writing. |
reference | string | no | 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. |
policy | string | no | Which of your policies to judge under. Absent means the project's policy, then your default; an account with none gets the shipped thresholds. |
project | string | no | Which of your projects the verdict is filed under. Absent means your default project. |
actor | string | no | Your own id for whoever wrote it. Filed with the verdict, and used to move the line when a policy asks for reputation. |
aidefaults tofalsehere. 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. Passai: truedeliberately 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:
| Endpoint | ai when you say nothing |
|---|---|
/text, /prompt, /image, /conversation | true. That is what those endpoints are for. |
/signup | false, and you can turn it on. |
/name, /email, /url | false, 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.