Skip to main content
The Limrun SDK uses the fetch API for HTTP requests. You can customize the fetch implementation and configure options like proxies for different runtime environments.

Custom Fetch Function

By default, the SDK expects a global fetch function. You can provide a custom implementation in two ways:

Polyfill Global Fetch

Replace the global fetch function:
import fetch from 'my-fetch';

globalThis.fetch = fetch;
This approach affects all code that uses fetch in your application.

Provide Fetch to Client

Pass a custom fetch function directly to the client:
import Limrun from '@limrun/api';
import fetch from 'my-fetch';

const client = new Limrun({ 
  fetch,
  apiKey: process.env.LIM_API_KEY,
});
This approach only affects the Limrun client instance.
Providing a custom fetch function to the client is the recommended approach as it doesn’t affect other parts of your application.

Fetch Options

You can set custom fetch options without overriding the fetch function using the fetchOptions parameter. This accepts any standard RequestInit options.

Client-Level Options

Set default options for all requests:
import Limrun from '@limrun/api';

const client = new Limrun({
  fetchOptions: {
    // RequestInit options
    keepalive: true,
    headers: {
      'X-Custom-Header': 'value',
    },
  },
});

Request-Level Options

Override options for individual requests:
const instance = await client.androidInstances.create({
  fetchOptions: {
    // These override client-level options
    priority: 'high',
  },
});
Request-specific fetchOptions override client-level options.

Configuring Proxies

Proxy configuration varies by runtime environment. Use fetchOptions to add runtime-specific proxy options.

Node.js with Undici

Node.js uses undici for its native fetch implementation:
import Limrun from '@limrun/api';
import * as undici from 'undici';

const proxyAgent = new undici.ProxyAgent('http://localhost:8888');

const client = new Limrun({
  apiKey: process.env.LIM_API_KEY,
  fetchOptions: {
    dispatcher: proxyAgent,
  },
});

// Use the client normally
const instance = await client.androidInstances.create();
See the undici ProxyAgent documentation for advanced proxy configurations.

Bun

Bun provides native proxy support through fetch options:
import Limrun from '@limrun/api';

const client = new Limrun({
  apiKey: process.env.LIM_API_KEY,
  fetchOptions: {
    proxy: 'http://localhost:8888',
  },
});

const instance = await client.androidInstances.create();
See Bun’s proxy documentation for more details.

Deno

Deno requires creating an HTTP client for proxy support:
import Limrun from 'npm:@limrun/api';

const httpClient = Deno.createHttpClient({ 
  proxy: { url: 'http://localhost:8888' } 
});

const client = new Limrun({
  apiKey: Deno.env.get('LIM_API_KEY'),
  fetchOptions: {
    client: httpClient,
  },
});

const instance = await client.androidInstances.create();
See Deno’s HTTP client documentation for advanced configurations.

Authentication Proxy Example

Combine custom fetch options with authentication:
import Limrun from '@limrun/api';
import * as undici from 'undici';

const proxyAgent = new undici.ProxyAgent({
  uri: 'http://localhost:8888',
  auth: 'username:password',
});

const client = new Limrun({
  apiKey: process.env.LIM_API_KEY,
  fetchOptions: {
    dispatcher: proxyAgent,
  },
});

HTTPS Proxy with Custom CA

For HTTPS proxies with custom certificates:
import Limrun from '@limrun/api';
import * as undici from 'undici';
import * as fs from 'fs';

const proxyAgent = new undici.ProxyAgent({
  uri: 'https://secure-proxy.example.com:8443',
  connect: {
    ca: fs.readFileSync('./ca-certificate.pem'),
  },
});

const client = new Limrun({
  apiKey: process.env.LIM_API_KEY,
  fetchOptions: {
    dispatcher: proxyAgent,
  },
});

Request Interceptor Pattern

Create a custom fetch wrapper to intercept and modify requests:
import Limrun from '@limrun/api';

const originalFetch = globalThis.fetch;

const customFetch: typeof fetch = async (input, init) => {
  console.log('Request:', input);
  
  // Add custom headers or modify request
  const modifiedInit = {
    ...init,
    headers: {
      ...init?.headers,
      'X-Request-Time': new Date().toISOString(),
    },
  };
  
  const response = await originalFetch(input, modifiedInit);
  
  console.log('Response status:', response.status);
  
  return response;
};

const client = new Limrun({
  fetch: customFetch,
  apiKey: process.env.LIM_API_KEY,
});

Retry with Custom Fetch

The SDK’s built-in retry mechanism works with custom fetch functions:
import Limrun from '@limrun/api';

let requestCount = 0;

const loggingFetch: typeof fetch = async (input, init) => {
  requestCount++;
  console.log(`Request #${requestCount}:`, input);
  return fetch(input, init);
};

const client = new Limrun({
  fetch: loggingFetch,
  maxRetries: 3,
  apiKey: process.env.LIM_API_KEY,
});

// Retries will be logged by loggingFetch
const instance = await client.androidInstances.create();

Testing with Mock Fetch

Use a mock fetch implementation for testing:
import Limrun from '@limrun/api';

const mockFetch: typeof fetch = async (input, init) => {
  return new Response(
    JSON.stringify({ id: 'test-instance', metadata: {} }),
    { 
      status: 200, 
      headers: { 'Content-Type': 'application/json' } 
    }
  );
};

const client = new Limrun({
  fetch: mockFetch,
  apiKey: 'test-key',
});

const instance = await client.androidInstances.create();
console.log(instance.id); // 'test-instance'

Browser Considerations

When using the SDK in browsers:
Browser security policies may prevent certain fetch customizations. CORS and CSP policies apply to all fetch requests.
import Limrun from '@limrun/api';

const client = new Limrun({
  apiKey: 'your-api-key',
  fetchOptions: {
    // Browser-compatible options
    credentials: 'include',
    mode: 'cors',
  },
});

Cloudflare Workers

Cloudflare Workers have their own fetch implementation:
import Limrun from '@limrun/api';

export default {
  async fetch(request: Request, env: Env) {
    const client = new Limrun({
      apiKey: env.LIM_API_KEY,
      fetchOptions: {
        // Cloudflare-specific options
        cf: {
          cacheTtl: 300,
          cacheEverything: true,
        },
      },
    });
    
    const instance = await client.androidInstances.create();
    return new Response(JSON.stringify(instance));
  },
};

Client Options

View all available client configuration options

Retries and Timeouts

Configure retry behavior and request timeouts

Build docs developers (and LLMs) love