API examples

Checking a submission from Node.js, PHP and Python, with a time limit and a safe fallback.

Each example sends one submission, waits at most two seconds, and lets the submission through if Cayve doesn’t answer. Read the key from an environment variable; never put it in code.

Node.js

export async function checkWithCayve(submission) {
  try {
    const res = await fetch('https://api.cayve.co/v1/check', {
      method: 'POST',
      headers: {
        authorization: `Bearer ${process.env.CAYVE_KEY}`,
        'content-type': 'application/json',
      },
      body: JSON.stringify(submission),
      signal: AbortSignal.timeout(2000),
    })
    if (!res.ok) return { verdict: 'allow' }
    const answer = await res.json()
    return answer.mode === 'shadow' ? { ...answer, verdict: 'allow' } : answer
  } catch {
    return { verdict: 'allow' } // Cayve unreachable: never block a real person
  }
}

const answer = await checkWithCayve({
  submission_id: `signup-${user.id}`,
  type: 'signup',
  content: { name: user.name, email: user.email },
  submitter: { ip: req.ip, user_agent: req.headers['user-agent'] },
})
if (answer.verdict === 'block') {
  // don't create the account; show the normal success page anyway
}

PHP

function cayve_check_submission(array $submission): array {
    $ch = curl_init('https://api.cayve.co/v1/check');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT_MS => 2000,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . getenv('CAYVE_KEY'),
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode($submission),
    ]);
    $body = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $answer = $status === 200 ? json_decode($body, true) : null;
    if (!$answer || $answer['mode'] === 'shadow') {
        return ['verdict' => 'allow'];
    }
    return $answer;
}

On WordPress, use the plugin’s cayve_check() instead; see The WordPress plugin.

Python

import os
import requests

def check_with_cayve(submission: dict) -> dict:
    try:
        res = requests.post(
            "https://api.cayve.co/v1/check",
            json=submission,
            headers={"Authorization": f"Bearer {os.environ['CAYVE_KEY']}"},
            timeout=2,
        )
        res.raise_for_status()
        answer = res.json()
    except requests.RequestException:
        return {"verdict": "allow"}
    return {**answer, "verdict": "allow"} if answer["mode"] == "shadow" else answer

Sending feedback

When someone on your team releases a held submission or confirms spam, tell Cayve:

curl https://api.cayve.co/v1/feedback \
  -H "Authorization: Bearer $CAYVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "detection_id": "chk_…", "label": "legit" }'

Testing

Use a test key while you build. A submission with cayve-test-block in any field is blocked, one with cayve-test-hold is held, and anything else is allowed. Test checks aren’t counted.

Something unclear or missing? Email hello@cayve.co.