Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.weblinq.dev/llms.txt

Use this file to discover all available pages before exploring further.

Security Best Practices

Protect your API keys and data when using WebLinq.

API Key Security

Never expose API keys in client-side code, logs, or public repositories

Environment Variables

Store API keys securely:
# .env file
WEBLINQ_API_KEY=your_api_key_here
// Always use environment variables
const response = await fetch('https://api.weblinq.dev/v1/web/markdown', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.WEBLINQ_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ url }),
});
Add .env to your .gitignore file

Key Rotation

Regularly rotate your API keys:
  1. Generate new key in dashboard
  2. Update your applications
  3. Test thoroughly
  4. Delete old key

Request Validation

URL Validation

Always validate URLs before making requests:
function validateUrl(url) {
  try {
    const parsed = new URL(url);

    // Only allow HTTP/HTTPS
    if (!['http:', 'https:'].includes(parsed.protocol)) {
      throw new Error('Invalid protocol');
    }

    // Block private networks
    const hostname = parsed.hostname;
    if (
      hostname === 'localhost' ||
      hostname.startsWith('127.') ||
      hostname.startsWith('192.168.') ||
      hostname.startsWith('10.') ||
      hostname.startsWith('172.')
    ) {
      throw new Error('Private networks not allowed');
    }

    return true;
  } catch (error) {
    throw new Error(`Invalid URL: ${error.message}`);
  }
}

Input Sanitization

Sanitize user inputs before processing:
function sanitizeInput(input) {
  // Remove potentially harmful characters
  return input
    .replace(/[<>]/g, '') // Remove HTML brackets
    .replace(/javascript:/gi, '') // Remove javascript: protocol
    .replace(/data:/gi, '') // Remove data: protocol
    .trim()
    .substring(0, 2000); // Limit length
}

Response Handling

Secure Content Processing

Validate API responses before using them:
function validateResponse(response) {
  // Check response structure
  if (!response.success) {
    throw new Error(response.error?.message || 'API request failed');
  }

  // Validate data exists
  if (!response.data) {
    throw new Error('No data in response');
  }

  return response.data;
}

// Usage
const response = await makeAPIRequest(url);
const safeData = validateResponse(response);

Content Filtering

Filter potentially malicious content:
function filterContent(content) {
  const suspiciousPatterns = [
    /<script[^>]*>/gi,
    /javascript:/gi,
    /on\w+\s*=/gi, // Event handlers like onclick=
    /<iframe[^>]*>/gi,
  ];

  for (const pattern of suspiciousPatterns) {
    if (pattern.test(content)) {
      console.warn('Suspicious content detected');
      content = content.replace(pattern, '');
    }
  }

  return content;
}

Error Handling

Never expose sensitive information in error messages:
async function safeAPICall(url) {
  try {
    validateUrl(url);

    const response = await fetch('https://api.weblinq.dev/v1/web/markdown', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.WEBLINQ_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ url }),
    });

    const data = await response.json();
    return validateResponse(data);
  } catch (error) {
    // Log detailed error for debugging
    console.error('API call failed:', error);

    // Return safe error message to user
    throw new Error('Failed to process request');
  }
}

Access Control

Server-Side Proxy

Never call WebLinq API directly from client-side code:
// ❌ NEVER do this in client-side code
// fetch('https://api.weblinq.dev/v1/web/markdown', {
//   headers: { 'Authorization': 'Bearer ' + API_KEY }
// });

// ✅ Create a server-side proxy instead
app.post('/api/extract-content', async (req, res) => {
  const { url } = req.body;

  try {
    validateUrl(url);
    const result = await callWebLinqAPI(url);
    res.json(result);
  } catch (error) {
    res.status(500).json({ error: 'Processing failed' });
  }
});

Rate Limiting

Implement request rate limiting in your application:
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 10, // limit each IP to 10 requests per windowMs
  message: 'Too many requests from this IP',
});

app.use('/api/extract-content', limiter);

Security Checklist

1

Secure API Keys

Store in environment variables, never in code
2

Validate Inputs

Check URLs and sanitize all user inputs
3

Use Server-Side Proxy

Never expose API keys to client-side code
4

Implement Rate Limiting

Protect your endpoints from abuse
5

Monitor Usage

Track API usage and watch for anomalies
6

Regular Key Rotation

Rotate API keys periodically