Scampilot API Documentation
Complete REST API for AI-powered scam detection and prevention
Introduction
Welcome to the Scampilot API documentation. This API provides programmatic access to our AI-powered scam detection and prevention platform.
Base URLs
Environment | URL |
---|---|
Production | https://scampilot.de/api |
Development | https://scampilot.test/api |
Features
- AI Checks: Submit text, links, images, or emails for scam analysis
- Questionnaires: Interactive risk assessment questionnaires
- Usage Tracking: Monitor API usage and limits
- Plan Management: Access subscription plan information
Authentication
Most endpoints require Bearer token authentication using Laravel Sanctum.
Creating an API Token
- Log in to your Scampilot account
- Navigate to Developer Portal → API Tokens at
/developer/tokens
- Click Create API Token
- Enter a name for the token and select permissions
- Copy the generated token (shown only once)
Using Your Token
Include the token in the Authorization
header of your requests:
Authorization: Bearer YOUR_API_TOKEN_HERE
Accept: application/json
Example Request
curl -X GET https://scampilot.de/api/user \
-H "Authorization: Bearer 1|abc123def456..." \
-H "Accept: application/json"
Security Note
Never commit tokens to version control. Use environment variables and rotate tokens regularly.
Rate Limiting
API requests are rate limited to prevent abuse.
User Type | Rate Limit |
---|---|
Authenticated Users | 60 requests per minute |
Anonymous Users | 10 requests per minute |
Rate Limit Headers
Response includes rate limit information:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 1633024800
Rate Limit Exceeded (429)
{
"message": "Too Many Attempts.",
"retry_after": 60
}
Error Handling
HTTP Status Codes
Code | Description |
---|---|
200 | Success |
201 | Created |
204 | No Content |
400 | Bad Request |
401 | Unauthorized |
403 | Forbidden |
404 | Not Found |
422 | Validation Error |
429 | Too Many Requests |
500 | Server Error |
Error Response Format
{
"message": "The given data was invalid.",
"errors": {
"email": [
"The email field is required."
]
}
}
User
Retrieve the currently authenticated user's information.
Headers
Authorization: Bearer {token}
Accept: application/json
Response (200 OK)
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"email_verified_at": "2025-10-09T12:00:00.000000Z",
"profile_photo_url": "https://...",
"created_at": "2025-10-09T10:00:00.000000Z",
"updated_at": "2025-10-09T11:00:00.000000Z"
}
Plans
Get all active subscription plans. No authentication required.
Response (200 OK)
{
"plans": [
{
"id": 1,
"name": "free",
"display_name": "Kostenlos",
"description": "Perfekt zum Ausprobieren",
"price_monthly": "0.00",
"price_yearly": "0.00",
"checks_per_day": 5,
"unlimited_checks": false,
"features": [
"5 Prüfungen pro Tag",
"Zugang zu Basis-Kursen"
]
}
]
}
Get the authenticated user's current subscription plan and usage.
Response (200 OK)
{
"plan": {
"name": "pro",
"display_name": "Scampilot Pro"
},
"usage": {
"today": 15,
"this_month": 342
},
"remaining": null,
"subscription": {
"is_subscribed": true,
"on_trial": false
}
}
AI Checks
Submit content for AI-powered scam analysis. Supports text, links, images, and emails.
Asynchronous Processing
Analysis is performed asynchronously. Use the status endpoint to poll for results.
Request Body (Text/Email)
{
"type": "text",
"content": "URGENT: Your bank account will be closed!..."
}
Request Body (Link)
{
"type": "link",
"url": "https://suspicious-site.com",
"content": "Optional context"
}
Response (201 Created)
{
"message": "Prüfung erstellt und wird analysiert",
"check": {
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"type": "text",
"webhook_status": "processing"
},
"status": "processing"
}
Check the current status of an AI analysis.
Response (200 OK)
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"status": "completed",
"risk_level": "warning",
"is_complete": true,
"is_pending": false,
"has_failed": false
}
Retrieve full details of a completed check.
Response (200 OK)
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"type": "text",
"risk_level": "warning",
"risk_score": 65,
"ai_explanation": "Diese Nachricht enthält...",
"ai_indicators": [
"Ungewöhnliche Dringlichkeit",
"Verdächtige Links"
],
"risk_text": "Vorsicht",
"risk_color": "yellow"
}
Usage Tracking
Get current usage statistics. Works for both authenticated and anonymous users.
Response (200 OK)
{
"usage": {
"today": 3,
"this_month": 45,
"all_time": 312
},
"remaining": 2,
"limit": 5,
"is_unlimited": false,
"plan": {
"name": "free",
"display_name": "Kostenlos"
}
}
Check if user can perform a specific action based on limits.
Response (200 OK)
{
"can_perform": true,
"remaining": 2,
"limit": 5,
"is_unlimited": false
}
Questionnaires
Get all active questionnaires.
Response (200 OK)
{
"questionnaires": [
{
"slug": "phishing-verdacht",
"title": "Phishing-Verdacht prüfen",
"category": "phishing",
"estimated_duration": 3
}
]
}
Begin a new questionnaire session.
Response (201 Created)
{
"message": "Fragebogen gestartet",
"response": {
"uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"started_at": "2025-10-09T20:30:00.000000Z"
}
}
Webhooks
Endpoint for n8n to send AI analysis results.
Request Body
{
"risk_level": "warning",
"risk_score": 65,
"explanation": "Diese Nachricht zeigt...",
"indicators": ["Dringlichkeit", "Verdächtige Links"]
}
Code Examples
// Create an AI check
const response = await fetch('https://scampilot.de/api/checks', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
type: 'text',
content: 'Suspicious message content...'
})
});
const data = await response.json();
const checkUuid = data.check.uuid;
// Poll for results
async function pollForResults(uuid) {
const statusRes = await fetch(
`https://scampilot.de/api/checks/${uuid}/status`
);
const status = await statusRes.json();
if (status.is_complete) {
const resultsRes = await fetch(
`https://scampilot.de/api/checks/${uuid}`
);
return await resultsRes.json();
}
// Wait 2 seconds and try again
await new Promise(resolve => setTimeout(resolve, 2000));
return pollForResults(uuid);
}
const results = await pollForResults(checkUuid);
console.log('Risk Level:', results.risk_level);
console.log('Explanation:', results.ai_explanation);
import requests
import time
# Create an AI check
response = requests.post(
'https://scampilot.de/api/checks',
json={
'type': 'text',
'content': 'Suspicious message content...'
}
)
check_uuid = response.json()['check']['uuid']
# Poll for results
def poll_for_results(uuid):
while True:
status_res = requests.get(
f'https://scampilot.de/api/checks/{uuid}/status'
)
status = status_res.json()
if status['is_complete']:
results_res = requests.get(
f'https://scampilot.de/api/checks/{uuid}'
)
return results_res.json()
time.sleep(2)
results = poll_for_results(check_uuid)
print(f"Risk Level: {results['risk_level']}")
print(f"Explanation: {results['ai_explanation']}")
'text',
'content' => 'Suspicious message content...'
]);
$checkUuid = $response->json()['check']['uuid'];
// Poll for results
function pollForResults($uuid) {
while (true) {
$statusRes = Http::get(
"https://scampilot.de/api/checks/{$uuid}/status"
);
$status = $statusRes->json();
if ($status['is_complete']) {
$resultsRes = Http::get(
"https://scampilot.de/api/checks/{$uuid}"
);
return $resultsRes->json();
}
sleep(2);
}
}
$results = pollForResults($checkUuid);
echo "Risk Level: " . $results['risk_level'] . "\n";
echo "Explanation: " . $results['ai_explanation'] . "\n";
# Create an AI check
curl -X POST https://scampilot.de/api/checks \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"type": "text",
"content": "Suspicious message content..."
}'
# Check status
curl https://scampilot.de/api/checks/{uuid}/status
# Get full results
curl https://scampilot.de/api/checks/{uuid}