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

# Publish

#### Publish to a URL with a 3 second delay and headers/body

```typescript theme={"system"}
import { Client } from "@upstash/qstash";

const client = new Client({ token: "<QSTASH_TOKEN>" });
const res = await client.publishJSON({
  url: "https://my-api...",
  body: { hello: "world" },
  headers: { "test-header": "test-value" },
  delay: "3s",
});
```

#### Publish to a URL group with a 3 second delay and headers/body

You create URL group on the QStash console or using the [URL Group API](/qstash/sdks/ts/examples/url-groups#create-a-url-group-and-add-2-endpoints)

```typescript theme={"system"}
import { Client } from "@upstash/qstash";

const client = new Client({ token: "<QSTASH_TOKEN>" });
const res = await client.publishJSON({
  urlGroup: "my-url-group",
  body: { hello: "world" },
  headers: { "test-header": "test-value" },
  delay: "3s",
});

// When publishing to a URL Group, the response is an array of messages for each URL in the URL Group
console.log(res[0].messageId);
```

#### Publish a method with a callback URL

[Callbacks](/qstash/features/callbacks) are useful for long running functions. Here, QStash will return the response
of the publish request to the callback URL.

We also change the `method` to `GET` in this use case so QStash will make a `GET` request to the `url`. The default
is `POST`.

```typescript theme={"system"}
import { Client } from "@upstash/qstash";

const client = new Client({ token: "<QSTASH_TOKEN>" });
const res = await client.publishJSON({
  url: "https://my-api...",
  body: { hello: "world" },
  callback: "https://my-callback...",
  failureCallback: "https://my-failure-callback...",
  method: "GET",
});
```

#### Configure the number of retries

The max number of retries is based on your [QStash plan](https://upstash.com/pricing/qstash)

```typescript theme={"system"}
import { Client } from "@upstash/qstash";

const client = new Client({ token: "<QSTASH_TOKEN>" });
const res = await client.publishJSON({
  url: "https://my-api...",
  body: { hello: "world" },
  retries: 1,
});
```

By default, the delay between retries is calculated using an exponential backoff algorithm. You can customize this using the `retry_delay` parameter. Check out [the retries documentation to learn more about custom retry delay values](/qstash/features/retry#custom-retry-delay).

#### Publish HTML content instead of JSON

```typescript theme={"system"}
import { Client } from "@upstash/qstash";

const client = new Client({ token: "<QSTASH_TOKEN>" });
const res = await client.publish({
  url: "https://my-api...",
  body: "<html><body><h1>Hello World</h1></body></html>",
  headers: {
    "Content-Type": "text/html",
  },
});
```

#### Publish a message with [content-based-deduplication](/qstash/features/deduplication)

```typescript theme={"system"}
import { Client } from "@upstash/qstash";

const client = new Client({ token: "<QSTASH_TOKEN>" });
const res = await client.publishJSON({
  url: "https://my-api...",
  body: { hello: "world" },
  contentBasedDeduplication: true,
});
```

#### Publish a message with timeout

Timeout value in seconds to use when calling a url ([See `Upstash-Timeout` in Publish Message page](/qstash/api-reference/messages/publish-a-message))

```typescript theme={"system"}
import { Client } from "@upstash/qstash";

const client = new Client({ token: "<QSTASH_TOKEN>" });
const res = await client.publishJSON({
  url: "https://my-api...",
  body: { hello: "world" },
  timeout: "30s" // 30 seconds timeout
});
```
