ScamVerify™

Testing

Use test API keys to validate your ScamVerify™ integration before going live, including CI/CD setup and example test scripts.

The ScamVerify™ API supports test keys that let you validate your integration without affecting your production quota.

Test Keys vs Live Keys

FeatureTest Key (sv_test_)Live Key (sv_live_)
Prefixsv_test_sv_live_
Rate limitsSame as your planSame as your plan
QuotasSame as your planSame as your plan
Data sourcesReal data (not mocked)Real data
BillingSeparate quota poolProduction quota pool

Test keys use the same real data sources as live keys. The results you get in test mode are identical to production results. The only difference is that test and live keys draw from separate quota pools, so testing does not consume your production allowance.

Creating Test Keys

  1. Log in to the ScamVerify™ Dashboard
  2. Navigate to API Keys
  3. Click Create Key
  4. Select Test as the key type
  5. Give it a descriptive name (e.g., "CI/CD Pipeline" or "Local Development")
  6. Copy the key immediately. It will only be shown once.

You can create multiple test keys for different environments (local development, staging, CI/CD).

Using Test Keys

Test keys work exactly like live keys. Just pass them in the Authorization header:

curl -X POST https://scamverify.ai/api/v1/phone/lookup \
  -H "Authorization: Bearer sv_test_abc123..." \
  -H "Content-Type: application/json" \
  -d '{"phone_number": "+12025551234"}'

The response will include all the same fields as a live lookup.

Testing in CI/CD

Store your test key as an environment variable in your CI/CD platform. Never commit API keys to source control.

Environment Variable Setup

# .env.test (gitignored)
SCAMVERIFY_API_KEY=sv_test_abc123...

GitHub Actions

# .github/workflows/test.yml
env:
  SCAMVERIFY_API_KEY: ${{ secrets.SCAMVERIFY_TEST_API_KEY }}

GitLab CI

# .gitlab-ci.yml
variables:
  SCAMVERIFY_API_KEY: $SCAMVERIFY_TEST_API_KEY

Example Test Scripts

import os
import pytest
import requests

API_KEY = os.environ["SCAMVERIFY_API_KEY"]
BASE_URL = "https://scamverify.ai/api/v1"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}


def test_phone_lookup_returns_verdict():
    response = requests.post(
        f"{BASE_URL}/phone/lookup",
        headers=HEADERS,
        json={"phone_number": "+12025551234"},
    )
    assert response.status_code == 200

    data = response.json()
    assert "risk_score" in data
    assert data["verdict"] in ("low_risk", "medium_risk", "high_risk")
    assert "explanation" in data


def test_url_verification_returns_verdict():
    response = requests.post(
        f"{BASE_URL}/url/verify",
        headers=HEADERS,
        json={"url": "https://example.com"},
    )
    assert response.status_code == 200

    data = response.json()
    assert "risk_score" in data
    assert data["verdict"] in ("low_risk", "medium_risk", "high_risk")


def test_invalid_phone_returns_400():
    response = requests.post(
        f"{BASE_URL}/phone/lookup",
        headers=HEADERS,
        json={"phone_number": "not-a-number"},
    )
    assert response.status_code == 400

    error = response.json()["error"]
    assert error["code"] == "validation_error"


def test_missing_api_key_returns_401():
    response = requests.post(
        f"{BASE_URL}/phone/lookup",
        headers={"Content-Type": "application/json"},
        json={"phone_number": "+12025551234"},
    )
    assert response.status_code == 401


def test_cached_lookup_does_not_consume_quota():
    # First lookup
    response1 = requests.post(
        f"{BASE_URL}/phone/lookup",
        headers=HEADERS,
        json={"phone_number": "+12025551234"},
    )
    assert response1.status_code == 200

    # Second lookup (should be cached)
    response2 = requests.post(
        f"{BASE_URL}/phone/lookup",
        headers=HEADERS,
        json={"phone_number": "+12025551234"},
    )
    assert response2.status_code == 200
    assert response2.json()["cached"] is True
import { describe, it, expect } from "vitest";

const API_KEY = process.env.SCAMVERIFY_API_KEY;
const BASE_URL = "https://scamverify.ai/api/v1";
const headers = {
  Authorization: `Bearer ${API_KEY}`,
  "Content-Type": "application/json",
};

describe("ScamVerify API", () => {
  it("should return a verdict for phone lookup", async () => {
    const response = await fetch(`${BASE_URL}/phone/lookup`, {
      method: "POST",
      headers,
      body: JSON.stringify({ phone_number: "+12025551234" }),
    });

    expect(response.status).toBe(200);
    const data = await response.json();
    expect(data).toHaveProperty("risk_score");
    expect(["low_risk", "medium_risk", "high_risk"]).toContain(data.verdict);
    expect(data).toHaveProperty("explanation");
  });

  it("should return a verdict for URL verification", async () => {
    const response = await fetch(`${BASE_URL}/url/verify`, {
      method: "POST",
      headers,
      body: JSON.stringify({ url: "https://example.com" }),
    });

    expect(response.status).toBe(200);
    const data = await response.json();
    expect(data).toHaveProperty("risk_score");
    expect(["low_risk", "medium_risk", "high_risk"]).toContain(data.verdict);
  });

  it("should return 400 for invalid phone number", async () => {
    const response = await fetch(`${BASE_URL}/phone/lookup`, {
      method: "POST",
      headers,
      body: JSON.stringify({ phone_number: "not-a-number" }),
    });

    expect(response.status).toBe(400);
    const data = await response.json();
    expect(data.error.code).toBe("validation_error");
  });

  it("should return 401 when API key is missing", async () => {
    const response = await fetch(`${BASE_URL}/phone/lookup`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ phone_number: "+12025551234" }),
    });

    expect(response.status).toBe(401);
  });

  it("should return cached result on second lookup", async () => {
    // First lookup
    await fetch(`${BASE_URL}/phone/lookup`, {
      method: "POST",
      headers,
      body: JSON.stringify({ phone_number: "+12025551234" }),
    });

    // Second lookup (should be cached)
    const response = await fetch(`${BASE_URL}/phone/lookup`, {
      method: "POST",
      headers,
      body: JSON.stringify({ phone_number: "+12025551234" }),
    });

    expect(response.status).toBe(200);
    const data = await response.json();
    expect(data.cached).toBe(true);
  });
});

Best Practices

  1. Use test keys in all non-production environments. Local development, staging, and CI/CD should always use sv_test_ keys.

  2. Never commit API keys to source control. Use environment variables or secrets management. Add .env.test to your .gitignore.

  3. Create separate test keys per environment. This lets you revoke a compromised key without disrupting other environments.

  4. Test error paths too. Validate that your integration handles 400, 401, 402, 429, and 500 responses correctly.

  5. Monitor test quota usage. Test keys have the same quota limits as your plan. If your CI/CD runs frequently, make sure your test quota is sufficient.

On this page