Dokumentasi API

Base URL: https://domain-kamu/api · Buka API Reference interaktif (OpenAPI) →

Autentikasi

Kirim API key di setiap request via header:

X-API-Key: sk-saring-xxxx...
# atau
Authorization: Bearer sk-saring-xxxx...

POST /v1/moderate

Moderasi satu teks berbahasa Indonesia (maks 5000 karakter).

curl -X POST https://domain-kamu/api/v1/moderate \
  -H "X-API-Key: sk-saring-xxxx" \
  -H "Content-Type: application/json" \
  -d '{"text": "kamu goblok banget!", "detailed": true}'

Parameter

FieldTipeKeterangan
textstringWajib. Teks yang dimoderasi.
detailedbooleanOpsional. true = sertakan matched_words & detail AI.

Respons

{
  "success": true,
  "data": {
    "is_offensive": true,
    "level": 3,                // 0-1 bersih, 2 ringan, 3 sedang, 4 kasar, 5 sangat kasar
    "level_label": "sedang",
    "confidence": 0.95,        // 0..1
    "matched_words": [
      {"kata": "goblok", "level": 3, "kategori": "sedang"}
    ],
    "method": "hybrid",        // wordlist | ai | hybrid
    "ai": {
      "ofensif_score": 0.98,
      "level": 3,
      "confidence": 0.9,
      "model": "openjev-0.1"
    },
    "cached": false,
    "processing_ms": 42
  }
}

Scope API Key

Setiap key bisa dibatasi hak aksesnya (atur saat pembuatan key di dashboard):

ScopeAkses
moderatePOST /v1/moderate, POST /v1/moderate/batch
usageGET /v1/usage, GET /v1/analytics (read-only)

Key tanpa scope moderate akan mendapat 403 saat memanggil endpoint moderasi. Cocok untuk key monitoring yang hanya boleh cek kuota.

POST /v1/moderate/batch

Moderasi hingga 50 teks sekaligus. Tiap teks dihitung 1 request terhadap kuota.

curl -X POST https://domain-kamu/api/v1/moderate/batch \
  -H "X-API-Key: sk-saring-xxxx" \
  -H "Content-Type: application/json" \
  -d '{"texts": ["komentar 1", "komentar 2", "komentar 3"]}'

Deteksi PII

Setiap respons otomatis menyertakan pii_detected — nomor HP, email, dan NIK Indonesia yang terdeteksi (dalam bentuk tersamarkan):

"pii_detected": [
  {"type": "phone", "masked": "0812*****678"},
  {"type": "email", "masked": "bo***@gmail.com"}
]

GET /v1/usage

Cek sisa kuota paket kamu.

curl https://domain-kamu/api/v1/usage -H "X-API-Key: sk-saring-xxxx"

{
  "success": true,
  "data": {
    "plan": "Pro",
    "requests_today": 1250,
    "daily_quota": 50000,
    "daily_remaining": 48750,
    "per_minute_quota": 300,
    "resets_at": "2026-10-04T00:00:00+07:00"
  }
}

GET /v1/analytics

Ambil ringkasan analitik (tren, kata terblokir, per key). Butuh scope usage. Parameter days opsional (1–90, default 30).

curl "https://domain-kamu/api/v1/analytics?days=7" -H "X-API-Key: sk-saring-xxxx"

{
  "success": true,
  "data": {
    "period_days": 7,
    "total_requests": 1250,
    "total_flagged": 87,
    "flag_rate_percent": 7.0,
    "trend": { "dates": [...], "requests": [...], "flagged": [...] },
    "top_words": [{ "kata": "goblok", "level": 2, "count": 31 }],
    "per_key": [{ "name": "Aplikasi Mobile", "requests": 900, "flagged": 60, "errors": 2 }]
  }
}

Kata Custom via API

Kelola kata custom akunmu tanpa buka dashboard. GET butuh scope usage, POST/DELETE butuh scope moderate.

# Daftar
curl https://domain-kamu/api/v1/custom-words -H "X-API-Key: sk-saring-xxxx"

# Tambah / ubah (block: paksa ofensif level 2-5, allow: putihkan)
curl -X POST https://domain-kamu/api/v1/custom-words \
  -H "X-API-Key: sk-saring-xxxx" -H "Content-Type: application/json" \
  -d '{"kata":"kadrun","action":"block","level":3}'

# Hapus
curl -X DELETE https://domain-kamu/api/v1/custom-words/kadrun \
  -H "X-API-Key: sk-saring-xxxx"

Mode Sandbox

Centang sandbox saat membuat API key untuk testing: tidak memakan kuota, tidak tercatat di usage log/analitik, dan response menyertakan "sandbox": true.

Rate Limit Headers

Setiap response API menyertakan:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 297
X-RateLimit-Reset: 42

Error

KodeArti
401API key tidak valid / tidak dikirim
403Tidak ada langganan aktif / scope tidak cukup
422Parameter tidak valid
429Kuota habis / rate limit

Contoh PHP (Laravel)

$res = Http::withHeaders(['X-API-Key' => config('services.saringid.key')])
    ->post('https://domain-kamu/api/v1/moderate', [
        'text' => $komentar,
    ])->json();

if ($res['data']['is_offensive']) {
    // tolak / tahan untuk review manual
}

Contoh Python

import requests

API_KEY = "sk-saring-xxxx"
BASE = "https://domain-kamu/api"

def moderasi(text: str) -> dict:
    r = requests.post(
        f"{BASE}/v1/moderate",
        headers={"X-API-Key": API_KEY},
        json={"text": text, "detailed": True},
        timeout=15,
    )
    r.raise_for_status()
    return r.json()["data"]

hasil = moderasi("komentar pengguna di sini")
if hasil["is_offensive"]:
    print("DITOLAK:", hasil["level_label"], hasil["matched_words"])

# Batch: hingga 50 teks sekaligus
r = requests.post(
    f"{BASE}/v1/moderate/batch",
    headers={"X-API-Key": API_KEY},
    json={"texts": ["komentar 1", "komentar 2"]},
    timeout=30,
).json()
print(f"{r['data']['flagged']} dari {r['data']['total']} teks bermasalah")

Contoh JavaScript (Node.js)

const API_KEY = "sk-saring-xxxx";
const BASE = "https://domain-kamu/api";

async function moderasi(text) {
  const res = await fetch(`${BASE}/v1/moderate`, {
    method: "POST",
    headers: { "X-API-Key": API_KEY, "Content-Type": "application/json" },
    body: JSON.stringify({ text, detailed: true }),
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return (await res.json()).data;
}

const hasil = await moderasi("komentar pengguna di sini");
if (hasil.is_offensive) {
  console.log("DITOLAK:", hasil.level_label, hasil.matched_words);
}
// PII yang bocor:
for (const pii of hasil.pii_detected) console.log("PII:", pii.type, pii.masked);

Webhook

Daftarkan URL di dashboard (menu Webhook). Saat konten ofensif terdeteksi, kami POST ke URL-mu:

POST https://aplikasi-kamu.com/webhook
X-SaringID-Signature: <hmac-sha256 dari body pakai secret-mu>

{
  "event": "moderation.flagged",
  "sent_at": "2026-10-03T12:00:00+07:00",
  "data": { "text": "...", "level": 3, "level_label": "sedang", ... }
}