Skip to main content
A hoisted fetch() function that is executed as a step function, allowing you to make HTTP requests from within workflow functions. This is the standard Fetch API wrapped as a step, providing durability and automatic retries for HTTP requests.

Signature

function fetch(
  input: RequestInfo | URL,
  init?: RequestInit
): Promise<Response>

Parameters

input
RequestInfo | URL
required
The URL to fetch. Can be a string, URL object, or Request object.
init
RequestInit
Request options.

Returns

Response
Promise<Response>
A Promise that resolves to a Response object.

Usage

Basic GET Request

Fetch data from an API:
import { fetch } from 'workflow';

export async function workflowWithFetch() {
  "use workflow";

  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  
  console.log('Fetched data:', data);
}

POST Request with JSON

Send JSON data:
import { fetch } from 'workflow';

export async function createUser(userData: any) {
  "use workflow";

  const response = await fetch('https://api.example.com/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(userData),
  });

  if (!response.ok) {
    throw new Error(`Failed to create user: ${response.statusText}`);
  }

  const user = await response.json();
  return user;
}

Custom Headers

Include authentication headers:
import { fetch } from 'workflow';

export async function authenticatedRequest(apiKey: string) {
  "use workflow";

  const response = await fetch('https://api.example.com/protected', {
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'X-Custom-Header': 'value',
    },
  });

  return await response.json();
}

Handle Different Status Codes

Check response status:
import { fetch } from 'workflow';

export async function handleStatusCodes() {
  "use workflow";

  const response = await fetch('https://api.example.com/data');

  if (response.status === 404) {
    console.log('Resource not found');
    return null;
  }

  if (response.status === 429) {
    console.log('Rate limited');
    throw new Error('Rate limit exceeded');
  }

  if (!response.ok) {
    throw new Error(`HTTP error: ${response.status}`);
  }

  return await response.json();
}

PUT Request

Update a resource:
import { fetch } from 'workflow';

export async function updateResource(id: string, updates: any) {
  "use workflow";

  const response = await fetch(`https://api.example.com/items/${id}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(updates),
  });

  return await response.json();
}

DELETE Request

Delete a resource:
import { fetch } from 'workflow';

export async function deleteResource(id: string) {
  "use workflow";

  const response = await fetch(`https://api.example.com/items/${id}`, {
    method: 'DELETE',
  });

  if (response.status === 204) {
    console.log('Resource deleted successfully');
    return true;
  }

  return false;
}

Form Data Upload

Submit form data:
import { fetch } from 'workflow';

export async function uploadFile(file: Blob, filename: string) {
  "use workflow";

  const formData = new FormData();
  formData.append('file', file, filename);
  formData.append('description', 'My file');

  const response = await fetch('https://api.example.com/upload', {
    method: 'POST',
    body: formData,
  });

  return await response.json();
}

Query Parameters

Construct URLs with query parameters:
import { fetch } from 'workflow';

export async function searchItems(query: string, limit: number) {
  "use workflow";

  const params = new URLSearchParams({
    q: query,
    limit: String(limit),
  });

  const response = await fetch(`https://api.example.com/search?${params}`);
  return await response.json();
}

Response Headers

Access response headers:
import { fetch } from 'workflow';

export async function checkHeaders() {
  "use workflow";

  const response = await fetch('https://api.example.com/data');
  
  const contentType = response.headers.get('Content-Type');
  const rateLimit = response.headers.get('X-RateLimit-Remaining');
  
  console.log('Content-Type:', contentType);
  console.log('Rate limit remaining:', rateLimit);
  
  return await response.json();
}

Important Notes

  • Must import from ‘workflow’: Do not use globalThis.fetch inside workflow functions. Always import and use fetch from the workflow package.
  • Executed as a step: Each fetch call is automatically wrapped as a step, providing durability and retry capabilities.
  • Automatic retries: Failed requests are automatically retried according to your step retry configuration.
  • Can only be used in workflows: The fetch function from workflow can only be called inside workflow functions (with "use workflow")
  • Standard Fetch API: Follows the Fetch API specification

Build docs developers (and LLMs) love