Quick Start
Get your API key and make your first request in under 5 minutes.
1Get Your API Key
Sign up for a free account to get your API key instantly, or try the live demo first.
Your API key looks like: sk_live_abc123...
2Make Your First Request
Choose your preferred language:
curl -X POST https://api.scorika.com/v1/score \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"ip": "1.2.3.4"
}'3Handle the Response
{
"data": {
"case_id": "case_abc123def456",
"score": 23,
"decision": "allow",
"confidence": 0.94,
"reason_codes": [
{
"code": "EMAIL_FREE_MAJOR",
"severity": "low",
"score_impact": 5,
"description": "Free email provider detected"
}
],
"signals": [
{
"type": "email",
"status": "success",
"score_delta": 5
},
{
"type": "ip",
"status": "success",
"score_delta": 0
}
]
},
"meta": {
"request_id": "req_xyz789",
"latency_ms": 142
}
}score: 0-30
Low risk - typically allow
score: 31-70
Medium risk - review recommended
score: 71-100
High risk - typically deny
Integration Guide
Production-ready client implementations with error handling, retry logic, and best practices.
Critical: Always Set a Timeout!
Never call Scorika API synchronously in checkout or registration flows without a timeout. If our API is slow or unavailable, your customers should not be blocked.
Recommended timeout: 3–5 seconds
Fallback decision: review (allow + async check)
Bedste praksis
✓ Do
- • Set timeout (3-5s) on all API calls
- • Implement fallback for timeouts/errors
- • Use environment variables for API keys
- • Log case_ids for debugging
✗ Don't
- • Block checkout on API errors
- • Make sync calls without timeout
- • Expose API keys in client-side code
- • Store raw API responses with PII
Production Client Examples
Copy one of these production-ready clients:
# scorika_client.py - Production-ready Scorika client
import requests
from requests.exceptions import Timeout, RequestException
from dataclasses import dataclass
from typing import Optional, List, Dict, Any
from enum import Enum
class Decision(Enum):
ALLOW = "allow"
REVIEW = "review"
DENY = "deny"
@dataclass
class ScoreResult:
case_id: Optional[str]
score: int
decision: Decision
confidence: float
signals: List[Dict]
fallback: bool = False # True if using fallback response
class ScorikaClient:
BASE_URL = "https://api.scorika.com/v1"
TIMEOUT = 5 # seconds - never block critical flows!
def __init__(self, api_key: str):
self.api_key = api_key
self.session = requests.Session()
self.session.headers.update({
"X-Api-Key": api_key,
"Content-Type": "application/json"
})
def score(
self,
email: Optional[str] = None,
ip: Optional[str] = None,
domain: Optional[str] = None,
url: Optional[str] = None
) -> ScoreResult:
"""Evaluate risk for given inputs with timeout protection."""
payload = {k: v for k, v in {
"email": email, "ip": ip, "domain": domain, "url": url
}.items() if v}
try:
response = self.session.post(
f"{self.BASE_URL}/score",
json=payload,
timeout=self.TIMEOUT # IMPORTANT: Always set timeout!
)
response.raise_for_status()
data = response.json()["data"]
return ScoreResult(
case_id=data["case_id"],
score=data["score"],
decision=Decision(data["decision"]),
confidence=data["confidence"],
signals=data.get("signals", [])
)
except (Timeout, RequestException) as e:
# Fallback: allow but flag for async review
print(f"Scorika unavailable: {e}, using fallback")
return ScoreResult(
case_id=None,
score=50,
decision=Decision.REVIEW,
confidence=0.0,
signals=[],
fallback=True
)
# Usage example
if __name__ == "__main__":
client = ScorikaClient("sk_live_your_api_key")
result = client.score(email="user@example.com", ip="1.2.3.4")
if result.fallback:
print("⚠ Using fallback - queue for async review")
elif result.decision == Decision.ALLOW:
print(f"✓ Allowed (score: {result.score})")
elif result.decision == Decision.REVIEW:
print(f"⚠ Review needed (score: {result.score})")
else:
print(f"✗ Denied (score: {result.score})")Error Handling
Always implement proper error handling for production use:
try { const result = await client.score({ email, ip }); // Handle decision} catch (error) { if (error.status === 429) { // Rate limited - back off and retry await sleep(retryAfter * 1000); return retry(); } else if (error.status >= 500) { // Server error - allow and log for investigation console.error('Scorika unavailable, allowing by default'); return { decision: 'allow', fallback: true }; } throw error;}Authentication
All API requests require authentication using an API key passed in the X-Api-Key header.
Security Note: Never expose your API key in client-side code. Always make API calls from your server.
curl -H "X-Api-Key: sk_live_your_api_key_here" \ https://api.scorika.com/v1/scoreError Handling
The API uses standard HTTP status codes and returns errors in a consistent JSON format.
| Status | Description |
|---|---|
200 | Success |
400 | Bad Request - Invalid parameters |
401 | Unauthorized - Invalid API key |
403 | Forbidden - Missing scope |
429 | Rate limit exceeded |
500 | Internal Server Error |
Example Error Response
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request parameters",
"details": [
{
"field": "email",
"code": "INVALID_FORMAT",
"message": "Email must be a valid email address"
}
],
"request_id": "req_xyz789",
"documentation_url": "https://docs.scorika.io/errors/VALIDATION_ERROR"
}
}POST /v1/score
Evaluate risk for a given set of inputs and return a risk score with decision.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | No* | Email address to evaluate |
ip | string | No* | IP address (IPv4 or IPv6) |
domain | string | No* | Domain name to check |
url | string | No* | Full URL to analyze |
* At least one input parameter is required.
Email Signal
The email signal analyzes email addresses for various risk indicators.
Reason Codes
disposable_emailEmail is from a known disposable email provider
free_providerEmail is from a free email provider (Gmail, Yahoo, etc.)
valid_mxDomain has valid MX records
IP Signal
The IP signal analyzes IP addresses for VPN, proxy, and other risk indicators.
Reason Codes
tor_exit_nodeIP is a known Tor exit node
vpn_detectedIP belongs to a known VPN provider
residentialIP appears to be a residential connection
Domain Signal
The domain signal analyzes domain names for age, reputation, and other indicators.
Reason Codes
newly_registeredDomain was registered within the last 30 days
young_domainDomain is less than 6 months old
established_domainDomain is more than 1 year old
SDKs & Developer Tools
Official SDKs, API collections, and developer tools to speed up your integration.
Python SDK
pip install scorika
Official Python client with async support, type hints, and retry logic.
Node.js SDK
npm install @scorika/client
TypeScript-first SDK with full type definitions and ESM support.
Ruby Gem
gem install scorika
Rails-friendly gem with ActiveSupport integration.
Developer Tools
Postman Collection
Import ready-to-use requests into Postman
OpenAPI Specification
Download the OpenAPI 3.0 spec for code generation
Interactive API Reference
Try API calls directly in your browser
Mock Server
Test your integration without hitting production
https://mock.scorika.com/v1