> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/unjs/ofetch/llms.txt
> Use this file to discover all available pages before exploring further.

# FetchOptions

> Complete configuration options for ofetch requests

## Overview

The `FetchOptions` interface extends the standard `RequestInit` and provides additional configuration for ofetch requests including base URL, query parameters, hooks, retry logic, and response parsing.

## Type Signature

```typescript theme={null}
export interface FetchOptions<R extends ResponseType = ResponseType, T = any>
  extends Omit<RequestInit, "body">,
    FetchHooks<T, R> {
  baseURL?: string;
  body?: RequestInit["body"] | Record<string, any>;
  ignoreResponseError?: boolean;
  params?: Record<string, any>; // @deprecated use query instead
  query?: Record<string, any>;
  parseResponse?: (responseText: string) => any;
  responseType?: R;
  duplex?: "half" | undefined;
  dispatcher?: InstanceType<typeof import("undici").Dispatcher>;
  agent?: unknown;
  timeout?: number;
  retry?: number | false;
  retryDelay?: number | ((context: FetchContext<T, R>) => number);
  retryStatusCodes?: number[];
}
```

## Options

### baseURL

<ParamField path="baseURL" type="string">
  Base URL to prepend to all requests. The request URL will be resolved against this base.
</ParamField>

```typescript theme={null}
await ofetch('/users', {
  baseURL: 'https://api.example.com'
})
// Fetches: https://api.example.com/users
```

### body

<ParamField path="body" type="RequestInit['body'] | Record<string, any>">
  Request body. Accepts standard fetch body types or plain objects. Objects are automatically serialized to JSON and appropriate headers are set.
</ParamField>

```typescript theme={null}
await ofetch('/users', {
  method: 'POST',
  body: { name: 'John', email: 'john@example.com' }
})
```

### ignoreResponseError

<ParamField path="ignoreResponseError" type="boolean" default="false">
  When `true`, prevents ofetch from throwing errors for 4xx and 5xx status codes. The response will be returned normally instead.
</ParamField>

```typescript theme={null}
const response = await ofetch('/users/404', {
  ignoreResponseError: true
})
```

### query

<ParamField path="query" type="Record<string, any>">
  Query parameters to append to the URL. Values are automatically URL-encoded.
</ParamField>

```typescript theme={null}
await ofetch('/users', {
  query: { page: 1, limit: 10 }
})
// Fetches: /users?page=1&limit=10
```

### params

<ParamField path="params" type="Record<string, any>">
  **Deprecated:** Use `query` instead. Query parameters to append to the URL.
</ParamField>

### parseResponse

<ParamField path="parseResponse" type="(responseText: string) => any">
  Custom function to parse response text. Defaults to `JSON.parse` for JSON responses.
</ParamField>

```typescript theme={null}
await ofetch('/data', {
  parseResponse: (text) => customParser(text)
})
```

### responseType

<ParamField path="responseType" type="ResponseType">
  Expected response type. One of: `"json"`, `"text"`, `"blob"`, `"arrayBuffer"`, or `"stream"`. Defaults to `"json"`. See [ResponseType](/api/types/response-types#responsetype).
</ParamField>

```typescript theme={null}
const blob = await ofetch('/image.png', {
  responseType: 'blob'
})

const text = await ofetch('/file.txt', {
  responseType: 'text'
})
```

### duplex

<ParamField path="duplex" type="'half' | undefined">
  **Experimental:** Set to `"half"` to enable duplex streaming. Automatically set when using a ReadableStream as body.
</ParamField>

```typescript theme={null}
await ofetch('/upload', {
  method: 'POST',
  body: readableStream,
  duplex: 'half'
})
```

### dispatcher

<ParamField path="dispatcher" type="InstanceType<typeof import('undici').Dispatcher>">
  Only supported in Node.js >= 18 using undici. Custom dispatcher for advanced request handling.
</ParamField>

See [undici documentation](https://undici.nodejs.org/#/docs/api/Dispatcher) for details.

### agent

<ParamField path="agent" type="unknown">
  Only supported in older Node.js versions using node-fetch-native polyfill. Custom agent for HTTP(S) requests.
</ParamField>

### timeout

<ParamField path="timeout" type="number">
  Request timeout in milliseconds. The request will be aborted if it takes longer than this value.
</ParamField>

```typescript theme={null}
await ofetch('/slow-endpoint', {
  timeout: 5000 // 5 seconds
})
```

### retry

<ParamField path="retry" type="number | false">
  Number of times to retry failed requests. Set to `false` to disable retries. Defaults to 1 for GET requests and 0 for other methods.
</ParamField>

```typescript theme={null}
await ofetch('/api/data', {
  retry: 3
})
```

### retryDelay

<ParamField path="retryDelay" type="number | ((context: FetchContext<T, R>) => number)">
  Delay between retries in milliseconds. Can be a number or a function that returns the delay based on the [FetchContext](/api/types/response-types#fetchcontext).
</ParamField>

```typescript theme={null}
// Fixed delay
await ofetch('/api/data', {
  retry: 3,
  retryDelay: 1000
})

// Dynamic delay (exponential backoff)
await ofetch('/api/data', {
  retry: 3,
  retryDelay: (context) => Math.pow(2, context.options.retry || 0) * 1000
})
```

### retryStatusCodes

<ParamField path="retryStatusCodes" type="number[]">
  HTTP status codes that should trigger a retry. Defaults to `[408, 409, 425, 429, 500, 502, 503, 504]`.
</ParamField>

```typescript theme={null}
await ofetch('/api/data', {
  retry: 3,
  retryStatusCodes: [429, 500, 502, 503]
})
```

## Hooks

FetchOptions extends [FetchHooks](/api/options/hooks), providing lifecycle hooks:

<ParamField path="onRequest" type="FetchHook | FetchHook[]">
  Called before the request is sent. See [onRequest](/api/options/hooks#onrequest).
</ParamField>

<ParamField path="onRequestError" type="FetchHook | FetchHook[]">
  Called when the request fails. See [onRequestError](/api/options/hooks#onrequesterror).
</ParamField>

<ParamField path="onResponse" type="FetchHook | FetchHook[]">
  Called after a successful response. See [onResponse](/api/options/hooks#onresponse).
</ParamField>

<ParamField path="onResponseError" type="FetchHook | FetchHook[]">
  Called when the response has an error status (4xx, 5xx). See [onResponseError](/api/options/hooks#onresponseerror).
</ParamField>

## Standard RequestInit Options

FetchOptions also includes all standard `RequestInit` options except `body` (which is redefined):

* `method` - HTTP method (GET, POST, PUT, DELETE, etc.)
* `headers` - Request headers
* `signal` - AbortSignal for request cancellation
* `credentials` - Credentials mode (omit, same-origin, include)
* `mode` - Request mode (cors, no-cors, same-origin)
* `redirect` - Redirect mode (follow, error, manual)
* `referrer` - Referrer URL
* `referrerPolicy` - Referrer policy
* `integrity` - Subresource integrity value
* `keepalive` - Keep connection alive
* `cache` - Cache mode

See [MDN RequestInit documentation](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) for details.

## Type Parameters

<ParamField path="R" type="ResponseType" default="ResponseType">
  The expected response type. See [ResponseType](/api/types/response-types#responsetype).
</ParamField>

<ParamField path="T" type="any" default="any">
  The expected type of the response data
</ParamField>

## Related

* [FetchHooks](/api/options/hooks) - Lifecycle hooks
* [ResponseType](/api/types/response-types#responsetype) - Response type options
* [FetchContext](/api/types/response-types#fetchcontext) - Context object passed to hooks
