Docs pages
Check a submission
Send each message from your server before you save it. You get a yes or no and a spam probability from 0 to 1. Find your key on the site page in your dashboard.
POSThttps://api.anti-spam.store/v1/check
curl
curl -X POST https://api.anti-spam.store/v1/check \
--max-time 5 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3f1c8a2e-5b8d-4c1e-9a7b-3d2e1f0a9b8c" \
-d '{"source":"form","fields":[{"type":"name","value":"Jane Cooper"},{"type":"email","value":"jane@acmeshop.com"},{"type":"textarea","value":"Hello, I would like a quote"}]}'
Node.js
import { randomUUID } from "node:crypto";
const result = await fetch("https://api.anti-spam.store/v1/check", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
"Idempotency-Key": randomUUID(), // a new one for each message
},
body: JSON.stringify({
source: "form",
fields: [
{ type: "name", value: name },
{ type: "email", value: email },
{ type: "textarea", value: message },
],
}),
signal: AbortSignal.timeout(5000), // also covers reading the answer
})
.then((res) => (res.ok ? res.json() : null))
.catch(() => null); // if we do not answer in time or the answer cannot be read, let the message through
if (result && result.status === "checked" && result.is_spam === true) {
// mark the message as spam
}
PHP
<?php
// A new Idempotency-Key (a UUID) for each message
$id = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex(random_bytes(16)), 4));
$ch = curl_init('https://api.anti-spam.store/v1/check');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5, // if we do not answer in time, let the message through
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
'Idempotency-Key: ' . $id,
],
CURLOPT_POSTFIELDS => json_encode([
'source' => 'form',
'fields' => [
['type' => 'name', 'value' => $name],
['type' => 'email', 'value' => $email],
['type' => 'textarea', 'value' => $message],
],
]),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// if we do not answer in time or the answer cannot be read, let the message through
$result = is_string($body) && $status === 200 ? json_decode($body, true) : null;
if (is_array($result) && ($result['status'] ?? '') === 'checked' && ($result['is_spam'] ?? null) === true) {
// mark the message as spam
}
Request
| Header | Type | Description |
|---|---|---|
Authorization | required | Bearer YOUR_API_KEY. The X-Api-Key header also works. |
Content-Type | required | application/json |
Idempotency-Key | required, UUID | A UUID you create once for each message. Send the same value again only when you resend the same message. |
{
"source": "comment",
"fields": [
{ "type": "name", "value": "Jane Cooper" },
{ "type": "email", "value": "jane@acmeshop.com" },
{ "type": "textarea", "value": "Hello, I would like a quote" }
],
"site": { "title": "Acme Shop", "tagline": "Handmade goods" },
"page": { "title": "Contact us", "meta_description": "Questions about an order? Write to us." }
}
| Field | Type | Description |
|---|---|---|
source | string, required | "comment" or "form". |
fields | array, required | What the visitor submitted, in order. Each item is { "type", "value" }. An empty array gives a skipped answer. |
fields[].type | string | name, email, phone, website, text or textarea. Other types are ignored. |
fields[].value | string, number, array or null | What the visitor entered. |
site | object | Optional. Your site: title and tagline. |
page | object | Optional. The page the message came from: title and meta_description. |
Send only what the visitor submitted. Other keys in the body are ignored, and we never ask for visitor IP addresses or browser details.
Response
{
"detection_id": "6f1c2a9e-5b8d-4c1e-9a7b-3d2e1f0a9b8c",
"status": "checked",
"spam_probability": 0.97,
"is_spam": true
}
| Field | Type | Description |
|---|---|---|
detection_id | string | A unique id for this answer. It is shown in your logs. |
status | string | "checked", or "skipped" when there was nothing to check. |
spam_probability | number, 0–1 | How likely the message is spam. Always 0 when skipped. |
is_spam | boolean | The verdict. Mark the message as spam only when it is true and status is "checked". |
More on each field and on repeated requests: Response.
Errors
| Status | Code | What to do |
|---|---|---|
401 | invalid_api_key | The key is missing, wrong or was replaced. Copy it again from the site page. |
422 | validation_failed | The body or the Idempotency-Key header is not valid. details says which field. |
429 | quota_exhausted | Your plan limit is reached. Let the message through. |
429 | rate_limited | Too many requests at once. Let the message through. |
503 | scoring_unavailable | The check could not be completed this time. Let the message through. |
If we are slow or cannot be reached, let the message through. Set a client timeout of 5 seconds, as the WordPress plugin does.
Every code and the error body: Errors.