API Documentation
Welcome to the SpamKiller API. Our AI-powered spam detection service helps you identify and filter spam submissions from contact forms, comments, and user-generated content.
Base URL
https://spamkiller.io/api/v1
Authentication
All API requests require authentication using an API key. You can obtain your API key from your project dashboard.
Authentication Methods
Include your API key in one of the following headers:
Method 1: Authorization Header (Recommended)
Authorization: Bearer YOUR_API_KEY
Method 2: Custom Header
X-API-Key: YOUR_API_KEY
Rate Limits
Rate limits are based on your subscription plan. When you exceed your limit, you'll receive a 429 Too Many Requests response.
| Plan | Monthly Limit | Price |
|---|---|---|
| Free | 100 validations | $0 |
| Starter | 1,000 validations | $19/month |
| Professional | 10,000 validations | $49/month |
| Enterprise | 100,000 validations | $149/month |
/status
Retrieve information about your project's subscription, plan details, and usage statistics.
Request Example
curl -X GET https://spamkiller.io/api/v1/status \
-H "Authorization: Bearer YOUR_API_KEY"
Response Example
{
"success": true,
"data": {
"project": {
"id": 1,
"name": "My First Project",
"slug": "my-first-project",
"active": true
},
"subscription": {
"status": "active",
"plan": {
"name": "Free",
"slug": "free",
"price": "0.00",
"currency": "USD",
"validations_per_month": 100
},
"usage": {
"validations_used": 3,
"validations_remaining": 97,
"validations_limit": 100,
"usage_percentage": 3
},
"billing": {
"starts_at": "2025-10-28T09:48:35+00:00",
"ends_at": null,
"validations_reset_at": "2025-11-28T09:48:35+00:00",
"payment_method": "manual"
}
}
}
}
/validate
Analyze content for spam detection using AI. This is the main endpoint for validating user submissions.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| context | string | Required | Free-text description of your app/website and form purpose (10-500 characters). Example: "E-commerce website selling outdoor equipment. Customer support contact form for product inquiries." |
| string | Required | Email address from the submission (must be valid email format) | |
| body | object | Required | Form fields as key-value pairs (e.g., {"message": "...", "name": "...", "phone": "..."}). At least one field required. |
| include_reasons | boolean | Optional | Include detailed analysis (Premium feature, default: false) |
Important: The context field is critical for accurate spam detection. Describe your application (e.g., "Blog", "E-commerce", "SaaS"), what it does, and the form type (contact, registration, newsletter, etc.).
Request Example
curl -X POST https://spamkiller.io/api/v1/validate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"context": "E-commerce website selling outdoor equipment. Customer support contact form.",
"email": "john.smith@company.com",
"body": {
"name": "John Smith",
"phone": "+1234567890",
"message": "Hello, I would like to schedule a meeting next week to discuss hiking boots."
}
}'
Response Example
{
"success": true,
"data": {
"validation_id": 123,
"is_spam": false,
"spam_score": 5,
"confidence": 95,
"reasons": [
"Message is professional, coherent, and grammatically correct.",
"Clear intent to discuss product offerings.",
"Email address format is professional and plausible."
],
"red_flags": [],
"recommendation": "Treat as a legitimate inquiry.",
"processing_time_ms": 8140
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| validation_id | integer | Unique ID for this validation |
| is_spam | boolean | Whether content is classified as spam |
| spam_score | integer | Spam score from 0-100 (higher = more likely spam) |
| confidence | integer | Confidence level (0-100) |
| reasons | array | Detailed reasons for the classification |
| red_flags | array | Specific red flags identified |
| recommendation | string | Actionable recommendation |
| processing_time_ms | integer | Processing time in milliseconds |
/validations/{id}/report-false-positive
Report a validation result as a false positive. This helps our AI model improve accuracy and learn from incorrect classifications. Your feedback is valuable for training and refining spam detection.
Use this endpoint when: The AI classified content as spam but it was actually legitimate (false positive). This feedback improves future accuracy.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| id | integer | The validation_id from the POST /validate response |
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| reason | string | Optional | Short reason for reporting (max 500 characters) |
| feedback | string | Optional | Detailed feedback about why this is a false positive (max 2000 characters) |
Request Example
curl -X POST https://spamkiller.io/api/v1/validations/12345/report-false-positive \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reason": "Legitimate customer inquiry",
"feedback": "This was a real customer asking about product availability. The AI incorrectly flagged it as spam because of the phrase ''limited time offer'' which the customer was referring to."
}'
Response Example (Success)
{
"success": true,
"message": "Thank you for your feedback. Our team will review this validation.",
"data": {
"validation_id": 12345,
"false_positive": true,
"reported_at": "2025-11-06T12:34:56+00:00"
}
}
Response Example (Already Reported)
{
"success": false,
"error": "This validation has already been reported as a false positive"
}
What happens after reporting? Your feedback is logged and flagged for admin review. The data is used to improve our AI model training. You can report each validation only once.
/validations/{id}/feedback
Submit a rating and optional comment for a validation result. This helps us understand overall satisfaction with the API accuracy and identify areas for improvement.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| id | integer | The validation_id from the POST /validate response |
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| rating | integer | Required | Rating from 1 (worst) to 5 (best) stars |
| comment | string | Optional | Additional feedback comment (max 1000 characters) |
Request Example
curl -X POST https://spamkiller.io/api/v1/validations/12345/feedback \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"rating": 5,
"comment": "Perfect detection! Caught a sophisticated spam attempt that other services missed."
}'
Response Example (Success)
{
"success": true,
"message": "Thank you for your feedback!",
"data": {
"validation_id": 12345,
"rating": 5,
"submitted_at": "2025-11-06T12:34:56+00:00"
}
}
Response Example (Already Submitted)
{
"success": false,
"error": "Feedback has already been submitted for this validation or rating is invalid"
}
Rating Guidelines: 5 stars = Perfect result, 4 stars = Good but minor issues, 3 stars = Acceptable, 2 stars = Needs improvement, 1 star = Incorrect result. You can rate each validation only once.
Webhooks
Webhooks allow you to receive real-time HTTP notifications when events occur in your SpamKiller account. Instead of polling for changes, webhooks push data to your server instantly.
✨ Advanced Feature
Webhooks are optional and primarily designed for Zapier integration and advanced use cases. For standard API usage, you only need POST /validate and GET /status endpoints.
When to use webhooks:
- ✅ Building Zapier/Make integrations (real-time triggers)
- ✅ Enterprise custom integrations requiring instant notifications
- ✅ Systems that need to react immediately to spam/credits events
- ❌ Not needed for basic spam validation workflows
Available Events
| Event | Description |
|---|---|
| validation.created | Fired when any validation is completed |
| validation.spam_detected | Fired when spam is detected |
| validation.legitimate_detected | Fired when legitimate content is detected |
| credits.low | Fired when credits fall below 10% |
| credits.depleted | Fired when credits reach 0 |
Create Webhook
POST https://spamkiller.io/api/v1/webhooks
Request Body
{
"url": "https://your-domain.com/webhooks/spam-analyzer",
"events": [
"validation.spam_detected",
"credits.low"
]
}
Response
{
"success": true,
"message": "Webhook created successfully",
"data": {
"id": 1,
"url": "https://your-domain.com/webhooks/spam-analyzer",
"events": ["validation.spam_detected", "credits.low"],
"secret": "wh_sec_abc123xyz789...",
"active": true,
"created_at": "2025-11-04T10:30:00Z"
}
}
⚠️ Important
The secret is returned only once. Store it securely to verify webhook signatures.
List Webhooks
GET https://spamkiller.io/api/v1/webhooks
Returns all webhooks for your project with delivery statistics (success rate, last delivery time, etc.).
Example Response
{
"success": true,
"data": [
{
"id": 1,
"url": "https://your-domain.com/webhooks/spam-analyzer",
"events": ["validation.spam_detected", "credits.low"],
"active": true,
"successful_deliveries": 150,
"failed_deliveries": 3,
"success_rate": 98.04,
"last_delivered_at": "2025-11-04T10:30:00Z",
"created_at": "2025-11-01T09:00:00Z"
}
]
}
Update Webhook
PUT https://spamkiller.io/api/v1/webhooks/{id}
Update webhook URL, events, or enable/disable it. All fields are optional.
Request Body
{
"events": ["validation.spam_detected", "validation.legitimate_detected"],
"active": true
}
Delete Webhook
DELETE https://spamkiller.io/api/v1/webhooks/{id}
Permanently delete a webhook subscription. This cannot be undone.
Response
{
"success": true,
"message": "Webhook deleted successfully"
}
Signature Verification
All webhooks include an HMAC SHA256 signature in the X-Webhook-Signature header. Always verify this signature to ensure the webhook is from SpamKiller.
PHP Example
<?php
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];
$secret = 'wh_sec_abc123xyz789...'; // Your webhook secret
$expectedSignature = hash_hmac('sha256', $payload, $secret);
if (hash_equals($expectedSignature, $signature)) {
// Signature is valid
$data = json_decode($payload, true);
// Process webhook...
http_response_code(200);
} else {
http_response_code(401);
die('Invalid signature');
}
Webhook Payload Format
{
"event": "validation.spam_detected",
"timestamp": "2025-11-04T10:30:00Z",
"webhook_id": 1,
"data": {
"id": 123,
"is_spam": true,
"spam_score": 85,
"confidence": 92,
"email": "spammer@example.com",
"project_id": 1,
"created_at": "2025-11-04T10:30:00Z"
}
}
Retry Logic
If your webhook endpoint fails, SpamKiller will automatically retry:
- Attempt 1: Immediate delivery
- Attempt 2: 5 minutes after first failure
- Attempt 3: 15 minutes after second failure
After 3 failed attempts, delivery is marked as permanently failed. Check webhook logs in your dashboard.
Error Handling
All error responses follow the same format with a success: false flag.
401 Unauthorized
Invalid or missing API key
{
"success": false,
"error": "Invalid API key",
"message": "The provided API key is invalid or inactive"
}
403 Forbidden
Project inactive or no active subscription
{
"success": false,
"error": "No active subscription",
"message": "This project does not have an active subscription"
}
422 Unprocessable Entity
Invalid request parameters
{
"success": false,
"error": "Validation failed",
"details": {
"email": ["The email field must be a valid email address."]
}
}
429 Too Many Requests
Rate limit exceeded
{
"success": false,
"error": "Validation limit exceeded",
"message": "You have reached your monthly validation limit.",
"details": {
"limit": 100,
"used": 100,
"resets_at": "2025-11-28T09:48:35+00:00"
}
}
Code Examples
PHP
<?php
$apiKey = 'YOUR_API_KEY';
$apiUrl = 'https://spamkiller.io/api/v1/validate';
$data = [
'context' => 'E-commerce website selling electronics. Contact form for customer support.',
'email' => 'customer@example.com',
'body' => [
'name' => 'John Doe',
'subject' => 'Product inquiry',
'message' => 'Hello, I would like more information about your products.'
]
];
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($response, true);
if ($httpCode === 200 && $result['success']) {
if ($result['data']['is_spam']) {
echo "Spam detected! Score: " . $result['data']['spam_score'];
} else {
echo "Content is legitimate!";
}
} else {
echo "Error: " . ($result['message'] ?? 'Unknown error');
}
JavaScript (Node.js)
const fetch = require('node-fetch');
const apiKey = 'YOUR_API_KEY';
const apiUrl = 'https://spamkiller.io/api/v1/validate';
const data = {
context: 'SaaS application for project management. User registration form.',
email: 'newuser@example.com',
body: {
username: 'johndoe',
company: 'Acme Corp',
phone: '+1234567890'
}
};
fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
if (result.success) {
if (result.data.is_spam) {
console.log(`Spam detected! Score: ${result.data.spam_score}`);
} else {
console.log('Content is legitimate!');
}
} else {
console.error(`Error: ${result.message}`);
}
})
.catch(error => console.error('Request failed:', error));
Python
import requests
api_key = 'YOUR_API_KEY'
api_url = 'https://spamkiller.io/api/v1/validate'
data = {
'context': 'Blog about technology and AI. Comment form on article pages.',
'email': 'reader@example.com',
'body': {
'author_name': 'Jane Smith',
'comment': 'Great article! Very informative and well-written.'
}
}
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {api_key}'
}
response = requests.post(api_url, json=data, headers=headers)
result = response.json()
if response.status_code == 200 and result['success']:
if result['data']['is_spam']:
print(f"Spam detected! Score: {result['data']['spam_score']}")
else:
print('Content is legitimate!')
else:
print(f"Error: {result.get('message', 'Unknown error')}")