|| "en_GB"

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

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)

Best Practices

✓ 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:

Error Handling Pattern
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/score

Error Handling

The API uses standard HTTP status codes and returns errors in a consistent JSON format.

StatusDescription
200Success
400Bad Request - Invalid parameters
401Unauthorized - Invalid API key
403Forbidden - Missing scope
429Rate limit exceeded
500Internal Server Error

Example Error Response

400 Bad Request
{
  "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

ParameterTypeRequiredDescription
emailstringNo*Email address to evaluate
ipstringNo*IP address (IPv4 or IPv6)
domainstringNo*Domain name to check
urlstringNo*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_email

Email is from a known disposable email provider

free_provider

Email is from a free email provider (Gmail, Yahoo, etc.)

valid_mx

Domain has valid MX records

IP Signal

The IP signal analyzes IP addresses for VPN, proxy, and other risk indicators.

Reason Codes

tor_exit_node

IP is a known Tor exit node

vpn_detected

IP belongs to a known VPN provider

residential

IP appears to be a residential connection

Domain Signal

The domain signal analyzes domain names for age, reputation, and other indicators.

Reason Codes

newly_registered

Domain was registered within the last 30 days

young_domain

Domain is less than 6 months old

established_domain

Domain 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.

Python 3.8+Coming Soon
📦

Node.js SDK

npm install @scorika/client

TypeScript-first SDK with full type definitions and ESM support.

Node 18+Coming Soon
💎

Ruby Gem

gem install scorika

Rails-friendly gem with ActiveSupport integration.

Ruby 3.0+Coming Soon

Developer Tools