# Conditional redirect from endpoint handlers?

**URL:** <https://softwaremill.community/t/conditional-redirect-from-endpoint-handlers/523>\
**Category:** tapir\
**Created:** [September 26, 2025, 8:16am UTC](https://softwaremill.community/t/conditional-redirect-from-endpoint-handlers/523 "2025-09-26T08:16:07Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![anatoliikmt](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/anatoliikmt/32/335_2.png) [@anatoliikmt](https://softwaremill.community/u/anatoliikmt)\
**Post date:** [September 26, 2025, 8:16am UTC](https://softwaremill.community/t/conditional-redirect-from-endpoint-handlers/523/1 "2025-09-26T08:16:07Z")

</div>

Hi!

I’m trying to do a redirect from an endpoint handler and so far am not having much luck doing it. Here’s my use case.

The app is a flashcards app for memorizing various information. There are, among others, two endpoints: `POST /decks`, to create a new deck of cards, and `GET /card_type/{id}/edit`, to edit a card type.

`/decks` creates a new deck and also a new default card type. This is done from the `handleSuccess` method. Now, at the end, I want the user to be redirected to the `/card_type/{id}/edit`, using the `{id}` created by the `/decks` handler. Here’s the code:

```auto
val createDeckEndpoint = endpoint
  .post.in("decks").in(formBody[Seq[(String, String)]]).out(stringBody)
  .out(header(Header.contentType(MediaType.TextHtml)))

val serverCreateDeckEndpoint = createDeckEndpoint
  .handleSuccess:
    (body: Seq[(String, String)]) =>
      val deck = /* Some logic to build the deck model */
      val deckId = service.decks.createDeck(deck)

      // Create the first card type
      val cardType = /* Some logic to build the CardType model */
      val cardTypeId = service.cardTypes.createCardType(cardType)

      // Redirect the user to the edit page for the newly created card type: /card_type/{cardTypeId}/edit

```

Does anyone have an idea how can I accomplish such a redirect?

---

<div class="post-metadata">

**Author:** ![adamw](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/adamw/32/28_2.png) [@adamw](https://softwaremill.community/u/adamw)\
**Post date:** [September 26, 2025, 8:37am UTC](https://softwaremill.community/t/conditional-redirect-from-endpoint-handlers/523/2 "2025-09-26T08:37:32Z")

</div>

I think you’ll need to add an output which is a location header, something like:

```auto
.out(header[String](HeaderNames.Location))

```

Then in the endpoint’s logic, you’ll need to provide the string value for the header

---

<div class="post-metadata">

**Author:** ![anatoliikmt](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/anatoliikmt/32/335_2.png) [@anatoliikmt](https://softwaremill.community/u/anatoliikmt)\
**Post date:** [September 26, 2025, 8:59am UTC](https://softwaremill.community/t/conditional-redirect-from-endpoint-handlers/523/3 "2025-09-26T08:59:19Z")

</div>

So you mean the handleSuccess will return a string “/card\_type/{id}/edit”, and it’ll be automatically interpreted as a value for the header?

Is it possible to set the header output type from the handler itself, conditional on the request body? Or it must be set outside the handler?

---

<div class="post-metadata">

**Author:** ![adamw](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/adamw/32/28_2.png) [@adamw](https://softwaremill.community/u/adamw)\
**Post date:** [September 26, 2025, 9:16am UTC](https://softwaremill.community/t/conditional-redirect-from-endpoint-handlers/523/4 "2025-09-26T09:16:52Z")

</div>

The server logic produces values as specified by the endpoint description, and maps them to headers/body. If you want to do conditional redirects, simply include an optional header in the output description:

```auto
.out(header[Option[String]](HeaderNames.Location))

```

The above means that the `Option[String]` that you return from your server logic will be mapped to the value of the location header (if present).

You cannot set response values in any other way

---

<div class="post-metadata">

**Author:** ![anatoliikmt](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/anatoliikmt/32/335_2.png) [@anatoliikmt](https://softwaremill.community/u/anatoliikmt)\
**Post date:** [September 26, 2025, 10:25am UTC](https://softwaremill.community/t/conditional-redirect-from-endpoint-handlers/523/5 "2025-09-26T10:25:26Z")

</div>

Another somewhat related question:

```auto
val editCardTypeEndpoint = endpoint
  .get.in("card_type" / path[Long] / "edit").out(stringBody)
  .out(header(Header.contentType(MediaType.TextHtml)))
  .out(header(Headers.hxPushUrl, s"/card_type/$cardTypeId/edit"))

```

Here I have an endpoint that is supposed to be accepting both AJAX and ordinary requests. In case of AJAX requests, I need to push a corresponding URL to the browser history, with the custom `Headers.hxPushUrl` header.

Is there a way to transfer the `in` parameter `path[Long]` into the `out` header’s `cardTypeId` variable? Note that in this case, I also emit the HTML body, so the trick with returning the header value from the body won’t work…

---

<div class="post-metadata">

**Author:** ![anatoliikmt](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/anatoliikmt/32/335_2.png) [@anatoliikmt](https://softwaremill.community/u/anatoliikmt)\
**Post date:** [September 26, 2025, 10:34am UTC](https://softwaremill.community/t/conditional-redirect-from-endpoint-handlers/523/6 "2025-09-26T10:34:05Z")

</div>

Ah, nevermind, I realised outputs may be chained into a tuple:

```auto
val editCardTypeEndpoint = endpoint
  .get.in("card_type" / path[Long] / "edit").out(stringBody)
  .out(header(Header.contentType(MediaType.TextHtml)))
  .out(header[String](Headers.hxPushUrl))

val serverEditCardTypeEndpoint = editCardTypeEndpoint
  .handleSuccess:
    (cardTypeId: Long) =>
      val cardType = service.cardTypes.getCardTypeById(cardTypeId)
      val body = html.upsertCardType(Some(cardType)).toString
      (body, s"/card_type/$cardTypeId/edit")

```
