# Forwarding a Request to an Upstream API

To forward a request to an upstream API ("proxy" a request), you can simply use a [`proxy-request` action](/flat/reference/actions/proxy-request.md), for example

```markup
<flow>
  <proxy-request>
  {
    "url": "https://httpbin.org/anything"
  }
  </proxy-request>
</flow>
```

to delegate the incoming request to [httpbin.org](https://httpbin.org/#/Anything).

The following [flow](/flat/reference/flow.md) shows a more advanced example:

```markup
<flow>
  <proxy-request>
  {
    {{// Replace the origin of the incoming request with the UPSTREAM_ORIGIN environment variable }}
    "origin": {{ $env/UPSTREAM_ORIGIN }},

    "headers": {
      {{// Set X-tra, drop X-Remove, copy Authorization }}
      "X-tra": "42",
      "X-Remove": "" {{,}}
      {{: $request/headers/authorization }}
    },

    "options": {
      "timeout": "exit-on-error": true,
      "validate-request": true,
      …
    }
  }
  </proxy-request>
</flow>
```

The `proxy-request` action lets you set the `origin` and modify the `headers` of the request. Everything else is set up automatically: The client request body will be forwarded as-is, any headers not intended for upstream will be dropped.

If you need to further modify the request, you'll have to configure a [`request` action](/flat/reference/actions/request.md) that forwards the incoming request with your modifications upstream. This gives you full control over the upstream request, but there's quite much thinking involved to get this fully right.

The following example illustrates, how such a request could look like. We just modify the `url`, copy `method` and `query` using [pair producers](/flat/reference/templating/pair-producer.md) and set the request `body` by referencing the [`$body` variable](/flat/reference/variables.md#predefined-variables):

```markup
<flow>
  <request>
  {
    {{// the URL for the upstream API}}
    "url": {{ replace($request/url, "^http://[^/]+", $env/UPSTREAM_URI) }},

    {{// copy the request method and query }}
    {{: $request/method | $request/query }},

    {{// set the request body}}
    "body": {
      "src": "$body"
    },
    {{// if set, copy specific headers, here foo and bar }}
    "headers": {
      {{: $request/headers/foo | $request/headers/bar }}
    },
    {{// if set, copy specific cookies, here SessionID and quux }}
    "cookies": {
      {{: $request/cookies/SessionID | $request/cookies/quux }}
    }
  }
  </request>

  <set-response-headers>
  {
    {{// pass through the upstream response status (defaults to 200) }}
    "status": {{ $upstream/main/status }}{{,}}
    {{// forward certain upstream response header fields }}
    {{: $upstream/main/headers/cache-control | $upstream/main/headers/set-cookie }}
  }
  </set-response-headers>
</flow>
```

Since we are implicitly using the default request ID `main` in the above example, the body together with its `Content-Type` is automatically set as the response body to be sent to the client.

The [`set-response-headers` action](/flat/reference/actions/set-response-headers.md) ensures that the HTTP status code of the upstream response and possibly additional header fields are correctly forwarded to the client.

The forwarded request will only have a body if the incoming request does. The `Content-Type` request and response headers are passed automatically with the body, therefore we don't have to copy them explicitly.

If the client and the upstream request URL paths do not share a common prefix, you can easily adjust the path by using `stripEndpoint` and `addPrefix`:

```javascript
{
  "origin": {{ $env/UPSTREAM_ORIGIN }},
  "stripEndpoint: true,
  "addPrefix": {{ $env/UPSTREAM_PATH_PREFIX }},
  …
}
```

Assuming the following `swagger.yaml` for `https://client.example.com/`

```yaml
basePath: /api
paths:
  /users/**:
    …
```

, `https://users.upstream.example.com` for `UPSTREAM_ORIGIN`, and `/v4` for `UPSTREAM_PATH_PREFIX`, a client request for `https://client.example.com/api/users/profile` will be forwarded to `https://users.upstream.example.com/v4/profile`.

## See also

* [Proxying requests to Upstream APIs](/flat/cookbook/proxy-requests.md) (cookbook)
* [`proxy-request` action](/flat/reference/actions/proxy-request.md) (reference)
* [`request` action](/flat/reference/actions/request.md) (reference)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sevenval.gitbook.io/flat/cookbook/forward-request-upstream.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
