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
| Feature | Test Key (sv_test_) | Live Key (sv_live_) |
|---|---|---|
| Prefix | sv_test_ | sv_live_ |
| Rate limits | Same as your plan | Same as your plan |
| Quotas | Same as your plan | Same as your plan |
| Data sources | Real data (not mocked) | Real data |
| Billing | Separate quota pool | Production 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
- Log in to the ScamVerify™ Dashboard
- Navigate to API Keys
- Click Create Key
- Select Test as the key type
- Give it a descriptive name (e.g., "CI/CD Pipeline" or "Local Development")
- 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_KEYExample 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 Trueimport { 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
-
Use test keys in all non-production environments. Local development, staging, and CI/CD should always use
sv_test_keys. -
Never commit API keys to source control. Use environment variables or secrets management. Add
.env.testto your.gitignore. -
Create separate test keys per environment. This lets you revoke a compromised key without disrupting other environments.
-
Test error paths too. Validate that your integration handles 400, 401, 402, 429, and 500 responses correctly.
-
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.