Anti-Spam
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

Request headers
HeaderTypeDescription
AuthorizationrequiredBearer YOUR_API_KEY. The X-Api-Key header also works.
Content-Typerequiredapplication/json
Idempotency-Keyrequired, UUIDA UUID you create once for each message. Send the same value again only when you resend the same message.
Body
{
  "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." }
}
Request body fields
FieldTypeDescription
sourcestring, required"comment" or "form".
fieldsarray, requiredWhat the visitor submitted, in order. Each item is { "type", "value" }. An empty array gives a skipped answer.
fields[].typestringname, email, phone, website, text or textarea. Other types are ignored.
fields[].valuestring, number, array or nullWhat the visitor entered.
siteobjectOptional. Your site: title and tagline.
pageobjectOptional. 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

200 OK
{
  "detection_id": "6f1c2a9e-5b8d-4c1e-9a7b-3d2e1f0a9b8c",
  "status": "checked",
  "spam_probability": 0.97,
  "is_spam": true
}
Response fields
FieldTypeDescription
detection_idstringA unique id for this answer. It is shown in your logs.
statusstring"checked", or "skipped" when there was nothing to check.
spam_probabilitynumber, 0–1How likely the message is spam. Always 0 when skipped.
is_spambooleanThe 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

Common errors
StatusCodeWhat to do
401invalid_api_keyThe key is missing, wrong or was replaced. Copy it again from the site page.
422validation_failedThe body or the Idempotency-Key header is not valid. details says which field.
429quota_exhaustedYour plan limit is reached. Let the message through.
429rate_limitedToo many requests at once. Let the message through.
503scoring_unavailableThe 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.