1. Functions
  2. Generic Fetch

Why use our fetch?

The fetch function provided by the trigger.dev SDK is a generic function that can be used to call any HTTP endpoint. It is designed to be used inside a Trigger.run function, and gives you the following benefits over using the standard fetch API:

  • We automatically retry with exponential back off (this can be configured with the options param)
  • The request and response are displayed in your Trigger.dev run dashboard for easy debugging
  • We automatically parse the response body as JSON and provide it as body on the response (and typed if you give provide a responseSchema)
  • We will retry the request reliably, even if your workflow is stopped, e.g. you deploy in the middle of a run. See Resumability for more information.

Usage

A fetch function is available to use inside a Trigger.run function through the context argument, and should be familiar for anyone who has used the standard fetch API, with a few modifications.

import { Trigger } from "@trigger.dev/sdk";

new Trigger({
  id: "fetch-example",
  name: "Fetch Example",
  on: customEvent({
    name: "example.fetch",
  }),
  run: async (event, ctx) => {
    await ctx.fetch("Example Key", "http://httpbin.org/get");
  },
}).listen();

Notice the first parameter to fetch is a key that is used to identify this call to fetch to support resumability. Please see the Resumability guide for more information.

The second parameter is the URL to fetch, and the third parameter is an optional options object that can be used to configure the request:

await ctx.fetch("Example Key", "http://httpbin.org/post", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: { hello: "world" },
});

Notice how the body is an object, and will be automatically stringified as JSON. This is because the fetch function currently only supports JSON request and response bodies. See Params for more information.

Using outside of a Trigger.run function

You can also import fetch and use it outside of a Trigger.run function:

httpBin.ts
import { fetch } from "@trigger.dev/sdk";

export function httpBinGet() {
  return fetch("Example Key", "http://httpbin.org/get");
}

Now you can use the exported httpBinGet function inside your Trigger.run function:

import { Trigger } from "@trigger.dev/sdk";
import { httpBinGet } from "./httpBin";

new Trigger({
  id: "fetch-example",
  name: "Fetch Example",
  on: customEvent({
    name: "example.fetch",
  }),
  run: async (event, ctx) => {
    await httpBinGet();
  },
}).listen();

This is useful if you want to wrap fetch to provide an SDK like experience inside your workflows.

Calling fetch when not inside of a workflow run will result in a thrown Error.

Response

Make sure to check response.ok, as non-2xx status codes will not throw an error and will instead return a response with ok set to false.

The return value of fetch is similar to a normal fetch response, but we will automatically parse the response body as JSON and provide it as body, like so:

const response = await ctx.fetch("Example Key", "http://httpbin.org/get");

if (response.body) {
  console.log(response.body.url); // http://httpbin.org/get
}

By default, the body is typed as any, but you can provide a Zod schema to validate the response body and get a more specific type:

import { z } from "zod";

const response = await ctx.fetch("Get HTTPBin", "http://httpbin.org/get", {
  responseSchema: z.object({
    url: z.string(),
    origin: z.string(),
    headers: z.record(z.string()),
  }),
});

Now the body will be typed as:

{
  url: string;
  origin: string;
  headers: Record<string, string>;
}

It’s okay to not be comprehensive with the schema, as long as the response body matches the schema, it will be valid. Do note that any properties not included in the schema will be excluded, unless you use .passthrough():

const response = await ctx.fetch("Get HTTPBin", "http://httpbin.org/get", {
  responseSchema: z.object({
    url: z.string(),
    origin: z.string(),
    headers: z.record(z.string()),
  }),
});

console.log(response.body); // Only includes url, origin, and headers

// Using passthrough():
const response = await ctx.fetch("Get HTTPBin", "http://httpbin.org/get", {
  responseSchema: z
    .object({
      url: z.string(),
      origin: z.string(),
      headers: z.record(z.string()),
    })
    .passthrough(),
});

console.log(response.body); // Includes url, origin, headers, and everything else

The fetch function currently only supports JSON request and response bodies.

Secret values

If you are using a header with a secret value, you can use our secureString tagged template to ensure that the value is not logged in the trigger.dev logs:

import { Trigger, secureString } from "@trigger.dev/sdk";

new Trigger({
  id: "fetch-example",
  name: "Fetch Example",
  on: customEvent({
    name: "example.fetch",
  }),
  run: async (event, ctx) => {
    await ctx.fetch("🔑 Secret API", "http://httpbin.org/post", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: secureString`Bearer ${process.env.SECRET_API_KEY}`,
      },
    });
  },
}).listen();

Which will show in the trigger.dev app as:

title

Retrying

By default, we will retry a failed request up to 10 times if it has one of the following status codes: 408, 429, 500, 502, 503, 504. You can override this behavior by providing a retry option:

await ctx.fetch("Example Key", "http://httpbin.org/get", {
  retry: {
    maxAttempts: 5,
    statusCodes: [408, 429, 500, 502, 503, 504, 521, 522, 524],
    minTimeout: 1000,
    maxTimeout: 10000,
    factor: 1.2,
  },
});
PropertyDescriptionDefault
enabledEnables retrying of failed requeststrue
factorThe exponential factor of backoff1.8
minTimeoutThe minimum amount of ms between retries1000
maxTimeoutThe maximum amount of ms between retries60000
statusCodesThe HTTP Status Codes that are retryable408, 429, 500, 502, 503, 504

If you’d like to disable retrying, simple pass in the retry option with enabled set to false:

await ctx.fetch("Example Key", "http://httpbin.org/get", {
  retry: {
    enabled: false,
  },
});

Params

keyRequired
string

A unique string. Please see the Keys and Resumability doc for more info.

urlRequired
string | URL

The URL to fetch.

options
object

Response

ok
boolean

Whether the response was successful. Non-2xx status codes will have ok = false.

body
object

The response body, parsed with the responseSchema if provided. Can be undefined if the response body is empty.

status
number

The HTTP status code.

headers
Record<string, string>

The response headers.