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

# Create Message

> Publish a message

## Request

<ParamField path="destination" type="string" required>
  Destination can either be a topic name or id that you configured in the
  Upstash console, or a valid url where the message gets sent to. Make sure the
  url is prefixed with a valid protocol (`http://` or `https://`)
</ParamField>

<ParamField body="body" type="string">
  The raw request message passed to the endpoints as is
</ParamField>

<ParamField header="Content-Type" type="string">
  ContentType is the MIME type of the message.

  We highly recommend sending a `Content-Type` header along, as this will help
  your destination API to understand the content of the message.

  For example `application/json`, `application/xml`, `application/octet-stream`,
  `text/plain`
</ParamField>

<ParamField header="Upstash-Method" type="string" default="POST">
  The HTTP method to use when sending a webhook to your API.
</ParamField>

<ParamField header="Upstash-Delay" type="string">
  Delay the message delivery.

  Format for this header is a number followed by duration abbreviation, like
  `10s`. Available durations are `s` (seconds), `m` (minutes), `h` (hours), `d`
  (days).

  example: "50s" | "3m" | "10h" | "1d"
</ParamField>

<ParamField header="Upstash-Retries" type="int" default={3}>
  How often should this message be retried in case the destination API is not available.

  The total number of deliveries is therefore capped at `1 + retries`

  Leave this empty to use the default value, (free tier: 3, paid tier: 5)

  The backoff duration in seconds is calculated as follows: `n` is the number of
  times the task has been retried.

  `min(86400, e ** (2 * n))`
</ParamField>

<ParamField header="Upstash-Callback" type="string">
  You can define a callback url that will be called after each attempt.
  See the content of what will be delivered to a callback [here](https://docs.upstash.com/qstash/features/callbacks#how-do-i-use-callbacks)

  * The callback url must be prefixed with a valid protocol (`http://` or `https://`)
  * Callbacks are charged as a regular message.
  * Callbacks will use the retry setting from the original request.
</ParamField>

<ParamField header="Upstash-Failure-Callback" type="string">
  You can define a failure callback url that will be called when a delivery is failed.
  That is when all the defined retries are exhausted.
  See the content of what will be delivered to a failure callback [here](https://docs.upstash.com/qstash/features/callbacks#what-is-a-failure-callback)

  * The failure callback url must be prefixed with a valid protocol (`http://` or `https://`)
  * Callbacks are charged as a regular message.
  * Callbacks will use the retry setting from the original request.
</ParamField>

<ParamField header="Upstash-Forward-*" type="string">
  You can send custom headers along with your message.

  To send a custom header, prefix the header name with `Upstash-Forward-`. We will
  strip efix and them to the destination API.

  example: "Upstash-Forward-My-Header: my-value" -> "My-Header: my-value"
</ParamField>

## Response

Either a single object or an array of objects is returned, depending on whether you have sent the message to a url or topic

<Expandable defaultOpen>
  <ResponseField name="messageId" type="string" required>
    The unique id of this message.
  </ResponseField>

  <ResponseField name="url" type="string" required>
    The url where the message was sent to.
  </ResponseField>

  <ResponseField name="deduplicated" type="boolean">
    Whether this message is a duplicate and was not sent to the destination.
  </ResponseField>
</Expandable>

<RequestExample>
  ```sh curl
  curl -X POST "https://qstash.upstash.io/v2/publish/https://www.example.com" \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -H "Upstash-Method: POST" \
    -H "Upstash-Delay: 10s" \
    -H "Upstash-Retries: 3" \
    -H "Upstash-Forward-Custom-Header: custom-value" \
    -d '{"message":"Hello, World!"}'
  ```

  ```js Node
  const response = await fetch(
    "https://qstash.upstash.io/v2/publish/https://www.example.com",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer <token>",
        "Content-Type": "application/json",
        "Upstash-Method": "POST",
        "Upstash-Delay": "10s",
        "Upstash-Retries": "3",
        "Upstash-Forward-Custom-Header": "custom-value",
      },
      body: JSON.stringify({
        message: "Hello, World!",
      }),
    }
  );
  ```

  ```python Python
  import requests

  headers = {
      'Authorization': 'Bearer <token>',
      'Content-Type': 'application/json',
      'Upstash-Method': 'POST',
      'Upstash-Delay': '10s',
      'Upstash-Retries': '3',
      'Upstash-Forward-Custom-Header': 'custom-value',
  }

  json_data = {
      'message': 'Hello, World!',
  }

  response = requests.post(
    'https://qstash.upstash.io/v2/publish/https://www.example.com',
     headers=headers,
     json=json_data
  )
  ```

  ```go Go
  var data = strings.NewReader(`{"message":"Hello, World!"}`)
  req, err := http.NewRequest("POST", "https://qstash.upstash.io/v2/publish/https://www.example.com", data)
  if err != nil {
    log.Fatal(err)
  }
  req.Header.Set("Authorization", "Bearer <token>")
  req.Header.Set("Content-Type", "application/json")
  req.Header.Set("Upstash-Method", "POST")
  req.Header.Set("Upstash-Delay", "10s")
  req.Header.Set("Upstash-Retries", "3")
  req.Header.Set("Upstash-Forward-Custom-Header", "custom-value")
  resp, err := http.DefaultClient.Do(req)
  if err != nil {
    log.Fatal(err)
  }
  defer resp.Body.Close()
  ```
</RequestExample>

<ResponseExample>
  ```json URL
  {
    "messageId": "msd_1234",
    "url": "https://www.example.com"
  }
  ```

  ```json Topic
  [
    {
      "messageId": "msd_1234",
      "url": "https://www.example.com"
    },
    {
      "messageId": "msd_5678",
      "url": "https://www.somewhere-else.com",
      "deduplicated": true
    }
  ]
  ```
</ResponseExample>
