---
title: HTTP
---
<BuiltinTable category={"http"}/>
:::info
Similar to other built-in functions, multiple calls to the `http.send` built-in function for a given request object
within a single policy evaluation query will always return the same value.
:::

:::danger
This built-in function **must not** be used for effecting changes in
external systems as OPA does not guarantee that the statement will be executed due
to automatic performance optimizations that are applied during policy evaluation.
:::

The `request` object parameter may contain the following fields:

| Field                          | Required | Type                 | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| ------------------------------ | -------- | -------------------- |   |
| `url`                          | yes      | `string`             | HTTP URL to specify in the request (e.g., `"https://www.openpolicyagent.org"`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `method`                       | yes      | `string`             | HTTP method to specify in request (e.g., `"GET"`, `"POST"`, `"PUT"`, etc.)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `body`                         | no       | `any`                | HTTP message body to include in request. The value will be serialized to JSON.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `raw_body`                     | no       | `string`             | HTTP message body to include in request. The value WILL NOT be serialized. Use this for non-JSON messages.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `headers`                      | no       | `object`             | HTTP headers to include in the request (e.g,. `{"X-Opa": "rules"}`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `enable_redirect`              | no       | `boolean`            | Follow HTTP redirects. Default: `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `force_json_decode`            | no       | `boolean`            | Decode the HTTP response message body as JSON even if the `Content-Type` header is missing. Default: `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `force_yaml_decode`            | no       | `boolean`            | Decode the HTTP response message body as YAML even if the `Content-Type` header is missing. Default: `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `tls_use_system_certs`         | no       | `boolean`            | Use the system certificate pool. Default: `true` when `tls_ca_cert`, `tls_ca_cert_file`, `tls_ca_cert_env_variable` are unset. **Ignored on Windows** due to the system certificate pool not being accessible in the same way as it is for other platforms.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `tls_ca_cert`                  | no       | `string`             | String containing a root certificate in PEM encoded format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `tls_ca_cert_file`             | no       | `string`             | Path to file containing a root certificate in PEM encoded format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `tls_ca_cert_env_variable`     | no       | `string`             | Environment variable containing a root certificate in PEM encoded format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `tls_client_cert`              | no       | `string`             | String containing a client certificate in PEM encoded format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `tls_client_cert_file`         | no       | `string`             | Path to file containing a client certificate in PEM encoded format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `tls_client_cert_env_variable` | no       | `string`             | Environment variable containing a client certificate in PEM encoded format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `tls_client_key`               | no       | `string`             | String containing a key in PEM encoded format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `tls_client_key_file`          | no       | `string`             | Path to file containing a key in PEM encoded format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `tls_client_key_env_variable`  | no       | `string`             | Environment variable containing a client key in PEM encoded format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `timeout`                      | no       | `string` or `number` | Timeout for the HTTP request with a default of 5 seconds (`5s`). Numbers provided are in nanoseconds. Strings must be a valid duration string where a duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". A zero timeout means no timeout.                                                                                                                                                                                                                                                                                                                                                                                         |
| `tls_insecure_skip_verify`     | no       | `bool`               | Allows for skipping TLS verification when calling a network endpoint. Not recommended for production.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `tls_server_name`              | no       | `string`             | Sets the hostname that is sent in the client Server Name Indication and that be will be used for server certificate validation. If this is not set, the value of the `Host` header (if present) will be used. If neither are set, the host name from the requested URL is used.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `cache`                        | no       | `boolean`            | Cache HTTP response across OPA queries. Default: `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `force_cache`                  | no       | `boolean`            | Cache HTTP response across OPA queries and override cache directives defined by the server. Default: `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `force_cache_duration_seconds` | no       | `number`             | If `force_cache` is set, this field specifies the duration in seconds for the freshness of a cached response.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `caching_mode`                 | no       | `string`             | Controls the format in which items are inserted into the inter-query cache. Allowed modes are `serialized` and `deserialized`. In the `serialized` mode, items will be serialized before inserting into the cache. This mode is helpful if memory conservation is preferred over higher latency during cache lookup. This is the default mode. In the `deserialized` mode, an item will be inserted in the cache without any serialization. This means when items are fetched from the cache, there won't be a need to decode them. This mode helps to make the cache lookup faster at the expense of more memory consumption. If this mode is enabled, the configured `caching.inter_query_builtin_cache.max_size_bytes` value will be ignored. This means an unlimited cache size will be assumed. |
| `cache_ignored_headers`        | no       | `list`               | List of header keys from `headers` parameter that should not considered when interacting with the cache. Default is `nil`, meaning all headers will be considered. **Important:** Note that if a cache entry exists with a subset/superset of headers that are considered in this request, it will lead to a cache miss.                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `raise_error`                  | no       | `bool`               | If `raise_error` is set, `http.send` will return an error that can halt policy evaluation when used in conjunction with the `strict-builtin-errors` option. Default: `true`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `max_retry_attempts`           | no       | `number`             | Number of times to retry a HTTP request when a network error is encountered. If provided, retries are performed with an exponential backoff delay. Default: `0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |

If the `Host` header is included in `headers`, its value will be used as the `Host` header of the request. The `url` parameter will continue to specify the server to connect to.

When sending HTTPS requests with client certificates at least one the following combinations must be included

- `tls_client_cert` and `tls_client_key`
- `tls_client_cert_file` and `tls_client_key_file`
- `tls_client_cert_env_variable` and `tls_client_key_env_variable`

:::info
To validate TLS server certificates, the user must also provide trusted root CA certificates through the `tls_ca_cert`, `tls_ca_cert_file` and `tls_ca_cert_env_variable` fields. If the `tls_use_system_certs` field is `true`, the system certificate pool will be used as well as any additional CA certificates.
:::

The `response` object parameter will contain the following fields:

| Field         | Type     | Description                                                                                                                                                                                                                                                                                            |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `status`      | `string` | HTTP status message (e.g., `"200 OK"`).                                                                                                                                                                                                                                                                |
| `status_code` | `number` | HTTP status code (e.g., `200`). If `raise_error` is `false`, this field will be set to `0` if `http.send` encounters an error.                                                                                                                                                                         |
| `body`        | `any`    | Any value. If the HTTP response message body was not deserialized from JSON or YAML (by force or via the expected Content-Type headers `application/json`; or `application/yaml` or `application/x-yaml`), this field is set to `null`.                                                                |
| `raw_body`    | `string` | The entire raw HTTP response message body represented as a string.                                                                                                                                                                                                                                     |
| `headers`     | `object` | An object containing the response headers. The values will be an array of strings, repeated headers are grouped under the same keys with all values in the array.                                                                                                                                      |
| `error`       | `object` | If `raise_error` is `false`, this field will represent the error encountered while running `http.send`. The `error` object contains a `message` key which holds the actual error message and a `code` key which represents if the error was caused due to a network issue or during policy evaluation. |

By default, an error returned by `http.send` halts the policy evaluation when used in conjunction with the `strict-builtin-errors` option that can be set when running evaluation.
This behaviour can be altered such that instead of halting evaluation, if `http.send` encounters an error, it can return a `response` object with `status_code`
set to `0` and `error` describing the actual error. This can be activated by setting the `raise_error` field
in the `request` object to `false`. Note that if the `strict-builtin-errors` option is not specified and `raise_error`
field is `true` (which is the default), an error returned by `http.send` will generate an undefined result.

If the `cache` field in the `request` object is `true`, `http.send` will return a cached response after it checks its
freshness and validity.

`http.send` uses the `Cache-Control` and `Expires` response headers to check the freshness of the cached response.
Specifically if the [max-age](https://tools.ietf.org/html/rfc7234#section-5.2.2.8) `Cache-Control` directive is set, `http.send`
will use it to determine if the cached response is fresh or not. If `max-age` is not set, the `Expires` header will be used instead.

If the cached response is stale, `http.send` uses the `Etag` and `Last-Modified` response headers to check with the server if the
cached response is in fact still fresh. If the server responds with a `200` (`OK`) response, `http.send` will update the cache
with the new response. On a `304` (`Not Modified`) server response, `http.send` will update the headers in cached response with
their corresponding values in the `304` response.

The `force_cache` field can be used to override the cache directives defined by the server. This field is used in
conjunction with the `force_cache_duration_seconds` field. If `force_cache` is `true`, then `force_cache_duration_seconds`
**must** be specified and `http.send` will use this value to check the freshness of the cached response.

Also, if `force_cache` is `true`, it overrides the `cache` field.

`http.send` only caches responses with the following HTTP status codes: `200`, `203`, `204`, `206`, `300`, `301`,
`404`, `405`, `410`, `414`, and `501`. This is behavior is as per https://www.rfc-editor.org/rfc/rfc7231#section-6.1 and
is enforced when caching responses within a single query or across queries via the `cache` and `force_cache` request fields.

:::info
`http.send` uses the `Date` response header to calculate the current age of the response by comparing it with the current time.
This value is used to determine the freshness of the cached response. As per https://tools.ietf.org/html/rfc7231#section-7.1.1.2,
an origin server MUST NOT send a `Date` header field if it does not have a clock capable of providing a reasonable
approximation of the current instance in Coordinated Universal Time. Hence, if `http.send` encounters a scenario where current
age of the response is represented as a negative duration, the cached response will be considered as stale.
:::

The table below shows examples of calling `http.send`:

| Example                                       | Comments                                                                                                                                                                                                          |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Accessing Google using System Cert Pool       | `http.send({"method": "get", "url": "https://www.google.com", "tls_use_system_certs": true })`                                                                                                                    |
| Files containing TLS material                 | `http.send({"method": "get", "url": "https://127.0.0.1:65331", "tls_ca_cert_file": "testdata/ca.pem", "tls_client_cert_file": "testdata/client-cert.pem", "tls_client_key_file": "testdata/client-key.pem"})`     |
| Environment variables containing TLS material | `http.send({"method": "get", "url": "https://127.0.0.1:65360", "tls_ca_cert_env_variable": "CLIENT_CA_ENV", "tls_client_cert_env_variable": "CLIENT_CERT_ENV", "tls_client_key_env_variable": "CLIENT_KEY_ENV"})` |
| Unix Socket URL Format                        | `http.send({"method": "get", "url": "unix://localhost/?socket=%F2path%F2file.socket"})`                                                                                                                           |

## Performance Metrics

When `?metrics=true` is specified in API requests, `http.send` operations expose the following per-query metrics:

| Metric | Description |
| ------ | ----------- |
| `timer_rego_builtin_http_send_ns` | Total time spent in `http.send` calls during query evaluation |
| `counter_rego_builtin_http_send_interquery_cache_hits` | Number of inter-query cache hits for `http.send` requests. Only appears when [inter-query caching is enabled](/docs/configuration/#caching) in OPA's configuration and the `http.send` request configuration has `cache` or `force_cache` set to `true` |
| `counter_rego_builtin_http_send_network_requests` | Number of actual network requests made, excluding cached responses |
