Redirections
Code Examples

JavaScript Examples

Integration examples using the Fetch API.

This page provides ready-to-integrate JavaScript code for the Redirections API using the native Fetch API. All examples work in both Node.js (18+) and modern browsers.

Configuration

Start by defining your API credentials and base URL:

const API_KEY = 'redir_live_your_key_here';
const PROJECT_ID = '<project_id>';
const BASE_URL = 'https://api.3xx.app';

Replace API_KEY and PROJECT_ID with your actual credentials.


Lookup a Redirect

This function looks up a redirect for a given path and returns the destination URL, status code, and match type.

async function lookupRedirect(path, version = null) {
  // Build query parameters
  const params = new URLSearchParams({
    project: PROJECT_ID,
    path: path,
  });

  if (version) {
    params.set('version', version);
  }

  // Make API request
  const response = await fetch(`${BASE_URL}/v1/lookup?${params}`, {
    method: 'GET',
    headers: {
      'X-API-Key': API_KEY,
    },
  });

  // Handle 204 No Content (no redirect found)
  if (response.status === 204) {
    return null;
  }

  // Handle errors
  if (!response.ok) {
    const error = await response.json();
    throw new Error(`API Error: ${error.error} (${error.code})`);
  }

  // Return successful result
  return await response.json();
}

// Usage example
(async () => {
  try {
    const result = await lookupRedirect('/old-blog');

    if (result) {
      console.log('Redirect found:');
      console.log(`  Destination: ${result.destination}`);
      console.log(`  Status Code: ${result.statusCode}`);
      console.log(`  Match Type: ${result.matchType}`);
    } else {
      console.log('No redirect found for this path');
    }
  } catch (error) {
    console.error('Lookup failed:', error.message);
  }
})();

Expected Output:

Redirect found:
  Destination: /blog
  Status Code: 301
  Match Type: exact

Export Redirects

This function downloads an export in the specified format and returns the content as text.

async function exportRedirects(format, version = null) {
  // Build query parameters
  const params = new URLSearchParams({
    project: PROJECT_ID,
    format: format,
  });

  if (version) {
    params.set('version', version);
  }

  // Make API request
  const response = await fetch(`${BASE_URL}/v1/export?${params}`, {
    method: 'GET',
    headers: {
      'X-API-Key': API_KEY,
    },
  });

  // Handle errors
  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Export failed: ${error.error} (${error.code})`);
  }

  // Return export content as text
  return await response.text();
}

// Usage example (Node.js)
import { writeFile } from 'fs/promises';

(async () => {
  try {
    const csvContent = await exportRedirects('csv');
    await writeFile('redirects.csv', csvContent, 'utf-8');
    console.log('Export saved to redirects.csv');
  } catch (error) {
    console.error('Export failed:', error.message);
  }
})();

// Usage example (Browser)
(async () => {
  try {
    const csvContent = await exportRedirects('csv');

    // Create download link
    const blob = new Blob([csvContent], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = 'redirects.csv';
    link.click();
    URL.revokeObjectURL(url);

    console.log('Export downloaded');
  } catch (error) {
    console.error('Export failed:', error.message);
  }
})();

Available formats: csv, nginx, nginx-map-exact, nginx-map-prefix, haproxy, haproxy-map-exact, haproxy-map-prefix


Error Handling

Handle API errors with proper error parsing and specific responses for different error codes.

async function lookupRedirectWithErrorHandling(path) {
  try {
    const params = new URLSearchParams({
      project: PROJECT_ID,
      path: path,
    });

    const response = await fetch(`${BASE_URL}/v1/lookup?${params}`, {
      method: 'GET',
      headers: {
        'X-API-Key': API_KEY,
      },
    });

    // Success: 204 No Content
    if (response.status === 204) {
      return null;
    }

    // Success: 200 OK
    if (response.ok) {
      return await response.json();
    }

    // Error: Parse error response
    const errorData = await response.json();

    // Handle specific error codes
    switch (errorData.code) {
      case 'INVALID_API_KEY':
        throw new Error('Invalid API key. Please check your credentials.');

      case 'MISSING_PATH':
        throw new Error('Path parameter is required.');

      case 'RATE_LIMIT_EXCEEDED':
        // Read Retry-After header
        const retryAfter = response.headers.get('Retry-After');
        if (retryAfter) {
          const waitSeconds = parseInt(retryAfter, 10);
          console.log(`Rate limited. Waiting ${waitSeconds} seconds...`);

          // Wait and retry
          await new Promise(resolve => setTimeout(resolve, waitSeconds * 1000));
          return lookupRedirectWithErrorHandling(path);
        }
        throw new Error('Rate limit exceeded. Please try again later.');

      case 'QUOTA_EXCEEDED':
        throw new Error('Monthly quota exceeded. Upgrade your plan or wait until next month.');

      default:
        throw new Error(`API error: ${errorData.error} (${errorData.code})`);
    }
  } catch (error) {
    if (error instanceof TypeError) {
      // Network error
      throw new Error('Network error: Unable to reach API. Check your connection.');
    }
    throw error;
  }
}

// Usage
(async () => {
  try {
    const result = await lookupRedirectWithErrorHandling('/old-blog');
    console.log('Success:', result);
  } catch (error) {
    console.error('Error:', error.message);
  }
})();

TypeScript Types

If using TypeScript, add these type definitions for better type safety:

interface LookupResponse {
  destination: string;
  statusCode: 301 | 302;
  matchType: 'exact' | 'starts_with';
}

interface ErrorResponse {
  error: string;
  code: string;
}

async function lookupRedirect(
  path: string,
  version?: number
): Promise<LookupResponse | null> {
  const params = new URLSearchParams({
    project: PROJECT_ID,
    path: path,
  });

  if (version) {
    params.set('version', version.toString());
  }

  const response = await fetch(`${BASE_URL}/v1/lookup?${params}`, {
    method: 'GET',
    headers: {
      'X-API-Key': API_KEY,
    },
  });

  if (response.status === 204) {
    return null;
  }

  if (!response.ok) {
    const error: ErrorResponse = await response.json();
    throw new Error(`API Error: ${error.error} (${error.code})`);
  }

  return await response.json();
}

Next Steps

For a complete reference of all error codes and their meanings, see the Error Reference page.