Skip to content

Troubleshooting

Common issues and solutions when using Vettly.

Authentication Issues

"Invalid API key" Error

Symptoms: 401 error, VettlyAuthError

Causes:

  • Wrong API key
  • Using test key (sk_test_...) in production
  • Key was revoked or deleted

Solutions:

  1. Check the key in your dashboard
  2. Ensure environment variable is set correctly
  3. Verify no extra whitespace in the key
  4. Create a new key if the old one was compromised
bash
# Check your key is set
echo $VETTLY_API_KEY

# Common issue: extra newline
export VETTLY_API_KEY="sk_live_xxxxx"  # Use quotes

API Key Not Loading

Symptoms: Empty or undefined API key

Solutions:

typescript
// Use server-side env (no NEXT_PUBLIC_ prefix)
const client = new ModerationClient({
  apiKey: process.env.VETTLY_API_KEY!  // Not NEXT_PUBLIC_
})
typescript
// Client-side needs VITE_ prefix
const client = new ModerationClient({
  apiKey: import.meta.env.VITE_VETTLY_API_KEY
})
python
import os

# Check env is loaded
api_key = os.environ.get("VETTLY_API_KEY")
if not api_key:
    raise ValueError("VETTLY_API_KEY not set")

client = ModerationClient(api_key=api_key)

Rate Limiting

"Rate limit exceeded" Error

Symptoms: 429 error, VettlyRateLimitError

Causes:

  • Too many requests per second
  • Burst of traffic exceeded limits

Solutions:

  1. Check your limits in the dashboard

  2. Implement client-side throttling:

typescript
import pLimit from 'p-limit'

const limit = pLimit(10)  // Max 10 concurrent requests

const results = await Promise.all(
  items.map(item => limit(() => client.check({
    content: item.text,
    policyId: 'moderate',
    contentType: 'text'
  })))
)
  1. Use batch endpoints for bulk operations:
typescript
const result = await client.batchCheck({
  policyId: 'moderate',
  items: items.map(item => ({
    id: item.id,
    content: item.text
  }))
})
  1. Upgrade your plan for higher limits

Retry-After Header

The SDK automatically respects Retry-After headers. If implementing manual retries:

typescript
try {
  await client.check({ ... })
} catch (error) {
  if (error instanceof VettlyRateLimitError) {
    const waitTime = error.retryAfter || 1
    await sleep(waitTime * 1000)
    // Retry...
  }
}

Quota Issues

"Quota exceeded" Error

Symptoms: 402 error, VettlyQuotaError

Causes:

  • Monthly API call limit reached
  • Plan limit exceeded

Solutions:

  1. Check usage in dashboard
  2. Upgrade your plan
  3. Implement caching for repeated content
typescript
const cache = new Map<string, CheckResponse>()

async function checkWithCache(content: string) {
  const hash = crypto.createHash('md5').update(content).digest('hex')

  if (cache.has(hash)) {
    return cache.get(hash)!
  }

  const result = await client.check({
    content,
    policyId: 'moderate',
    contentType: 'text'
  })

  cache.set(hash, result)
  return result
}

Content Issues

Content Too Large

Symptoms: 422 error, request rejected

Limits:

  • Text: 32KB (approximately 8,000 words)
  • Images: 20MB
  • Video: 100MB

Solutions:

  1. Truncate long text:
typescript
const MAX_LENGTH = 30000  // ~30KB

const truncated = content.length > MAX_LENGTH
  ? content.substring(0, MAX_LENGTH)
  : content

await client.check({
  content: truncated,
  policyId: 'moderate',
  contentType: 'text'
})
  1. Compress images before sending

  2. Use chunk-based processing for very long content

Invalid Content Type

Symptoms: 422 error mentioning content type

Solutions:

  • Ensure contentType matches the actual content
  • For images, use data:image/... format or valid URL
  • For base64, include the data URL prefix
typescript
// Wrong
client.check({
  content: rawBase64,  // Missing data URL prefix
  contentType: 'image'
})

// Correct
client.check({
  content: `data:image/jpeg;base64,${rawBase64}`,
  contentType: 'image'
})

Timeout Issues

Request Timeout

Symptoms: Timeout error, no response

Causes:

  • Large content taking too long
  • Network issues
  • API under high load

Solutions:

  1. Increase timeout:
typescript
const client = new ModerationClient({
  apiKey: 'sk_live_...',
  timeout: 60000  // 60 seconds
})
  1. Use async batch for large operations:
typescript
const { batchId } = await client.batchCheckAsync({
  policyId: 'moderate',
  items: largeItemList,
  webhookUrl: 'https://myapp.com/webhook'
})
// Results delivered via webhook

Webhook Issues

Webhooks Not Receiving Events

Symptoms: No webhook deliveries

Checklist:

  1. Webhook URL is publicly accessible
  2. URL uses HTTPS
  3. Endpoint responds with 2xx status
  4. Webhook is enabled in dashboard

Test your endpoint:

typescript
// Send test event
await client.testWebhook(webhookId, 'decision.blocked')

Invalid Signature

Symptoms: Signature verification fails

Common issues:

  • Wrong webhook secret
  • Modifying payload before verification
  • Using wrong encoding

Correct implementation:

typescript
// Get raw body BEFORE any parsing
app.post('/webhooks/vettly',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const payload = req.body.toString()  // Raw string
    const signature = req.headers['x-vettly-signature']

    if (!verifyWebhookSignature(payload, signature, secret)) {
      return res.status(401).send('Invalid signature')
    }

    // Now parse
    const event = constructWebhookEvent(payload)
    // ...
  }
)

Webhook Timeout

Symptoms: Webhook marked as failed, retrying

Solutions:

  • Respond within 5 seconds
  • Process events asynchronously
typescript
app.post('/webhooks/vettly', async (req, res) => {
  // Verify signature...
  const event = constructWebhookEvent(payload)

  // Respond immediately
  res.status(200).send('OK')

  // Process async
  await processEventAsync(event)
})

SDK-Specific Issues

TypeScript: Module Not Found

Error: Cannot find module '@nextauralabs/vettly-sdk'

Solutions:

bash
# Clear and reinstall
rm -rf node_modules package-lock.json
npm install

Python: Import Error

Error: ModuleNotFoundError: No module named 'vettly'

Solutions:

bash
# Ensure correct Python version
python3 -m pip install vettly

# Or with virtual env
source venv/bin/activate
pip install vettly

Python: Async Issues

Error: RuntimeError: Event loop is already running

Solution: Use the async client properly:

python
# Wrong: mixing sync and async
client = ModerationClient(...)
await client.check(...)  # ModerationClient is sync!

# Correct: use AsyncModerationClient
async with AsyncModerationClient(api_key="...") as client:
    result = await client.check(content="...", policy_id="moderate")

Getting Help

If you're still stuck:

  1. Check Status: status.vettly.dev
  2. Search Issues: GitHub Issues
  3. Ask Community: GitHub Discussions
  4. Contact Support: support@vettly.dev

When reporting issues, include:

  • SDK version (vettly --version or check package.json)
  • Error message and stack trace
  • Minimal reproduction code
  • Decision ID if available