CheckLayer API User Guide
Learn how to authenticate requests, call each REST endpoint, interpret responses, and keep integrations healthy across environments.
Overview
This guide walks through the CheckLayer REST API: how to retrieve API credentials, which endpoints are available, how payloads should be structured, and what responses to expect. Use it as the canonical integration reference for engineering, QA, and support teams.
Base URL
https://api.checklayer.io/api/v1
Formats
JSON request and response payloads
Versioning
Current stable version: v1
Quick Start Checklist
-
1
Generate an API key
Create an API token in the CheckLayer dashboard under API Tokens.
-
2
Verify the key
Call GET /api/v1/verify to ensure the token is active before integrating.
-
3
Send a test request
Call POST /api/v1/check with the cURL snippet below or import the endpoint into Postman.
-
4
Persist detection IDs
Log the returned detection_id for later audits and feedback submissions.
-
5
Monitor usage
Keep an eye on GET /api/v1/stats (or your internal metrics) to confirm traffic stays within plan limits.
Getting an API Key
- Register or sign in at https://checklayer.io/.
- Open your workspace settings and select API Tokens.
- Create a new key or copy an existing one. Newly generated keys are shown once—store them securely.
- If the UI does not allow self-service tokens on your plan, contact support or your account manager to provision a key.
Authentication
- Send Authorization: Bearer <YOUR_API_KEY> with every request.
- Compatibility headers include X-API-Key or an api_key field in the body/query string (discouraged in production).
- All traffic must use HTTPS. Missing, invalid, or revoked keys return 401 Unauthorized.
Rate Limiting
Each API key is limited to 50 requests per minute and a monthly quota defined by your plan. Exceeding these limits triggers 429 Rate Limit Exceeded responses with remaining: 0.
Headers & Payload Requirements
Set both headers on every call and send valid JSON payloads:
- Content-Type: application/json
- Accept: application/json
POST /api/v1/check
Full spam analysis for longer submissions such as emails, support tickets, or contact forms.
| Field | Type | Required | Description |
|---|---|---|---|
| message | string | Yes | Text to analyse (email body, form submission, chat message, etc.). |
| string | No | Sender email address (max 255 characters). | |
| name | string | No | Author name or nickname. |
| ip | string | No | User IPv4/IPv6 address. Defaults to the request IP if omitted. |
| timestamp | integer | No | UNIX timestamp for when the content was created. |
| user_agent | string | No | Browser or client User-Agent string. |
| website_url | string (URL) | No | Source page URL for the submission. |
| domain | string | No | Domain associated with the content (helpful for account validation). |
Sample Request (cURL)
curl -X POST "https://api.checklayer.io/api/v1/check" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "Hi! I can deliver 1,000 followers for just $5.",
"email": "[email protected]",
"name": "Cheap Leads Bot",
"ip": "203.0.113.42",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
"website_url": "https://blog.example.com/contact"
}'
Sample Response
{
"detection_id": "4b6c9c42-63d6-4eac-9ff7-1965b0dbc1c9",
"is_spam": true,
"total_score": 86.4,
"threshold": 50,
"execution_time": 121.37,
"timestamp": "2025-02-15T11:32:18.214Z"
}
Response Fields
| Field | Type | Description |
|---|---|---|
| detection_id | string | Unique identifier you can reference in audits, feedback, or support tickets. |
| is_spam | boolean | true means the spam threshold was met or exceeded. |
| total_score | float | Aggregate spam score. Higher values indicate stronger spam signals. |
| threshold | float | Score required for the detector to classify content as spam. |
| execution_time | float | Processing time in milliseconds. |
| timestamp | string (ISO 8601) | Timestamp when the response was generated. |
PHP Example (Guzzle)
<?php
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://api.checklayer.io/api/v1/',
'timeout' => 5.0,
]);
$response = $client->post('check', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('CHECKLAYER_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'message' => 'Need more traffic? Buy 10k visitors today!',
'email' => '[email protected]',
'ip' => '198.51.100.87',
],
]);
$result = json_decode($response->getBody()->getContents(), true);
if ($result['is_spam']) {
// Flag the content or block the user here.
}
Keep the detection_id alongside the original content to support audits or feedback submissions.
POST /api/v1/check-comment
Optimised for comment or review widgets where you only need a yes/no verdict and a lightweight payload. Accepts the same fields as /check.
| Field | Type | Required | Description |
|---|---|---|---|
| message | string | Yes | Comment or review text to evaluate. |
| string | No | Commenter email address, if collected. | |
| name | string | No | Display name or nickname shown publicly. |
| ip | string | No | Originating IP address; falls back to the request IP if omitted. |
| timestamp | integer | No | UNIX timestamp when the comment was submitted. |
| user_agent | string | No | Client or browser user agent string. |
Sample Request (cURL)
curl -X POST "https://api.checklayer.io/api/v1/check-comment" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "Great article! Check out my crypto scheme at http://spam.biz",
"email": "[email protected]",
"ip": "198.51.100.12"
}'
Sample Response
{
"detection_id": "207e3b47-5f47-42dd-bc0b-775c3e387c33",
"is_spam": false,
"total_score": 18.45,
"threshold": 50,
"execution_time": 64.09,
"timestamp": "2025-02-15T11:34:09.817Z"
}
| Field | Type | Description |
|---|---|---|
| detection_id | string | Identifier to use for logging, audits, or feedback. |
| is_spam | boolean | Final verdict for the comment payload. |
| total_score | float | Aggregate score calculated for the comment. |
| threshold | float | Score threshold used for classification. |
| execution_time | float | Processing time in milliseconds. |
| timestamp | string (ISO 8601) | Response generation time. |
Use this endpoint when you want the smallest possible JSON response and do not need the extended signal report.
POST /api/v1/feedback
Submit moderator feedback to improve detection quality.
| Field | Type | Required | Description |
|---|---|---|---|
| detection_id | string | Yes | Identifier returned by /check or /check-comment. |
| is_spam | boolean | Yes | Final label chosen by your system or moderators. |
Sample Request (cURL)
curl -X POST "https://api.checklayer.io/api/v1/feedback" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"detection_id": "4b6c9c42-63d6-4eac-9ff7-1965b0dbc1c9",
"is_spam": false
}'
Sample Response
{
"success": true,
"message": "Feedback submitted and will be processed shortly",
"data": {
"detection_id": "4b6c9c42-63d6-4eac-9ff7-1965b0dbc1c9",
"user_status": true,
"queued_at": "2025-02-15T11:36:42.055Z"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| success | boolean | Indicates whether the feedback request was accepted for processing. |
| message | string | Human-readable confirmation or error message. |
| data.detection_id | string | Echoes the detection you submitted, so you can correlate the acknowledgement. |
| data.user_status | boolean | The classification you supplied (true for spam, false for ham). |
| data.queued_at | string (ISO 8601) | Server timestamp showing when the feedback job entered the queue. |
Error responses follow the same structure described in Common Errors (for example, 404 when a detection_id is unknown).
GET /api/v1/verify
Confirm an API key is active and view metadata about the owner.
Request Requirements
- Method: GET
- Path: /api/v1/verify
- Headers: Authorization: Bearer YOUR_API_KEY, Accept: application/json
- No query parameters or body payload are required.
Sample Response
{
"valid": true,
"message": "API key is valid",
"key_info": {
"name": "Production key",
"created_at": "2024-11-19T09:22:11Z",
"last_used_at": "2025-02-15T11:36:55Z"
},
"user_info": {
"id": 481,
"email": "[email protected]",
"name": "Example Ops"
},
"timestamp": "2025-02-15T11:36:55.301Z"
}
Response Fields
| Field | Type | Description |
|---|---|---|
| valid | boolean | Indicates whether the presented key is active. |
| message | string | Human-readable summary of the verification result. |
| key_info.name | string | Friendly label assigned to the API token. |
| key_info.created_at | string (ISO 8601) | Date and time the token was created. |
| key_info.last_used_at | string (ISO 8601 | null) | Timestamp of the most recent successful API call using this key. |
| user_info.id | integer | Internal identifier of the user who owns the key. |
| user_info.email | string | Contact email associated with the account. |
| user_info.name | string | Name of the user tied to the key (if provided). |
| timestamp | string (ISO 8601) | Server timestamp when the verification response was generated. |
GET /api/v1/stats
Retrieve current plan usage to manage quotas and alerting.
Request Requirements
- Method: GET
- Path: /api/v1/stats
- Headers: Authorization: Bearer YOUR_API_KEY, Accept: application/json
- No body parameters are required; stats are derived from the authenticated account.
Sample Response
{
"success": true,
"data": {
"plan": {
"name": "Business",
"id": 3
},
"usage": {
"total_requests": 50000,
"used_requests": 3125,
"remaining_requests": 46875,
"usage_percentage": 6.25
},
"period": {
"month": 2,
"year": 2025
}
},
"timestamp": "2025-02-15T11:37:12.648Z"
}
Response Fields
| Field | Type | Description |
|---|---|---|
| success | boolean | Indicates whether the stats lookup succeeded. |
| data.plan.name | string | Name of the plan associated with the key. |
| data.plan.id | integer | Internal identifier for the plan. |
| data.usage.total_requests | integer | Monthly quota allocated to the plan. |
| data.usage.used_requests | integer | Requests consumed in the current billing period. |
| data.usage.remaining_requests | integer | Requests still available before the quota resets. |
| data.usage.usage_percentage | float | Percentage of the allocated quota already used. |
| data.period.month | integer | Month the stats snapshot refers to. |
| data.period.year | integer | Year the stats snapshot refers to. |
| timestamp | string (ISO 8601) | Server timestamp when the stats were generated. |
Common Errors
| Status | When it happens | Sample payload |
|---|---|---|
| 401 Unauthorized | Key missing, invalid, or revoked. | {"error":"Invalid API key","message":"The provided API key is not valid"} |
| 403 Forbidden | User has no active subscription plan. | {"error":"No Plan","message":"User has no active plan"} |
| 404 Not Found | detection_id not found during feedback submission. | {"error":"Detection not found","error_details":"No spam detection found with this detection_id"} |
| 422 Unprocessable Entity | Validation rules violated. | {"error":"Validation failed","errors":{"message":["The message field is required."]}} |
| 429 Too Many Requests | Per-minute or monthly quota exceeded. | {"error":"Rate Limit Exceeded","message":"Monthly request limit exceeded","limit":50000,"used":50000,"remaining":0} |
| 500 Internal Server Error | Unexpected server-side exception. | {"error":"Internal server error","message":"An error occurred while processing your request."} |
Testing & Sample Payloads
- Spam sample: “Exclusive offer! Buy verified leads now and get 300% ROI. Click here: http://cheap-leads.biz/offer.”
- Ham sample: “Hey team, attached is the weekly report. Let me know if you need any follow-up data.”
- Verify keys first with GET /verify. Regenerate tokens if you receive 401.
- Store API keys in environment variables or CI secrets (e.g., CHECKLAYER_API_KEY), never hardcode them.
Integration Tips
- Persist every detection_id with the source content for audits and feedback.
- Retry on 429 with exponential backoff and monitor remaining quotas.
- Add a deployment or runtime health-check that calls /verify to ensure credentials remain active.
- Avoid sending unnecessary personal data to minimise compliance risk.
- Keep SDKs and client libraries updated; API changes are announced in the changelog.
Troubleshooting FAQ
Getting 401 Unauthorized?
Confirm the request includes Authorization: Bearer YOUR_API_KEY and that the key is still listed under API Tokens. Keys are revoked immediately when deleted.
Seeing 403 or 429 responses?
Check /stats to confirm plan status and remaining quota. Upgrade or wait for the next billing cycle if limits are reached.
Need deeper insight into a detection?
Share the detection_id, timestamp, and sample payload with support. Logs are indexed by those fields.
Experiencing high latency?
Send requests from regions close to CheckLayer infrastructure and consider asynchronous workflows if p95 latency affects user flows.
Support
- Technical support: [email protected]
- Incident channel: Slack/Teams #checklayer-alerts (ask your account team for access).
- Billing or quota changes: Contact your account manager or the support team.