---
title: "OkHttp Integration"
description: "Learn how to capture tracing information of the OkHttp client."
url: https://docs.sentry.io/platforms/java/guides/spring-boot/tracing/instrumentation/okhttp/
---

# OkHttp Integration | Sentry for Spring Boot

To be able to capture transactions, you'll need to first [set up tracing](https://docs.sentry.io/platforms/java/guides/spring-boot/tracing.md).

The `sentry-okhttp` library provides [OkHttp](https://github.com/square/okhttp) support for Sentry via the `SentryOkHttpInterceptor` and the `SentryOkHttpEventListener`, which create a span for each outgoing HTTP request executed with an OkHttp client. The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tree/main/sentry-okhttp).

## [Install](https://docs.sentry.io/platforms/java/guides/spring-boot/tracing/instrumentation/okhttp.md#install)

To install the integration:

```xml
<dependency>
    <groupId>io.sentry</groupId>
    <artifactId>sentry-okhttp</artifactId>
    <version>8.37.1</version>
</dependency>
```

For other dependency managers, see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-okhttp).

## [Configure](https://docs.sentry.io/platforms/java/guides/spring-boot/tracing/instrumentation/okhttp.md#configure)

Configuration should happen once you create your `OkHttpClient` instance.

```kotlin
import okhttp3.OkHttpClient
import io.sentry.okhttp.SentryOkHttpEventListener
import io.sentry.okhttp.SentryOkHttpInterceptor

private val client = OkHttpClient.Builder()
  .addInterceptor(SentryOkHttpInterceptor())
  .eventListener(SentryOkHttpEventListener())
  .build()
```

The SDK uses the `SentryOkHttpInterceptor` to support [Distributed Tracing](https://docs.sentry.io/product/sentry-basics/tracing/distributed-tracing.md) and creates a span for any HTTP call. The SDK can give more in-depth information through the `SentryOkHttpEventListener` by creating a span for each operation reported by OkHttp, including DNS setup, proxy selection, HTTP connect, SSL setup, send request headers, send request body, receive response headers, and receive response body.

## [Verify](https://docs.sentry.io/platforms/java/guides/spring-boot/tracing/instrumentation/okhttp.md#verify)

This snippet includes a HTTP Request and captures an intentional message, so you can test that everything is working as soon as you set it up:

```kotlin
import io.sentry.Sentry
import java.io.IOException
import okhttp3.OkHttpClient
import okhttp3.Request

@Throws(IOException::class)
fun run(url: String): String? {
  val request = Request.Builder()
    .url(url)
    .build()

  val bodyStr = client
    .newCall(request)
    .execute()
    .body?.toString()

  Sentry.captureMessage("The Message $bodyStr")

  return bodyStr
}
```

To view and resolve the recorded message, log into [sentry.io](https://sentry.io) and open your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved.

## [Customize the Recorded Span](https://docs.sentry.io/platforms/java/guides/spring-boot/tracing/instrumentation/okhttp.md#customize-the-recorded-span)

The captured span can be customized or dropped with a `BeforeSpanCallback`:

```kotlin
import io.sentry.ISpan
import io.sentry.okhttp.SentryOkHttpInterceptor
import okhttp3.Request
import okhttp3.Response

class CustomBeforeSpanCallback : SentryOkHttpInterceptor.BeforeSpanCallback {
  override fun execute(span: ISpan, request: Request, response: Response?): ISpan? {
    return if (request.url.toUri().toString().contains("/admin")) {
      null
    } else {
      span
    }
  }
}
```

The callback instance must be set on the `SentryOkHttpInterceptor` once you create your `OkHttpClient` instance.

```kotlin
import okhttp3.OkHttpClient
import io.sentry.okhttp.SentryOkHttpEventListener
import io.sentry.okhttp.SentryOkHttpInterceptor

private val client = OkHttpClient.Builder()
  .eventListener(SentryOkHttpEventListener())
  .addInterceptor(SentryOkHttpInterceptor(CustomBeforeSpanCallback()))
  .build()
```

## [Using Multiple Event Listeners](https://docs.sentry.io/platforms/java/guides/spring-boot/tracing/instrumentation/okhttp.md#using-multiple-event-listeners)

The integration's event listener can propagate calls to another `EventListener` or `EventListener.Factory` that's set on the `SentryOkHttpEventListener` once you create your `OkHttpClient` instance.

```kotlin
import okhttp3.OkHttpClient
import io.sentry.okhttp.SentryOkHttpEventListener
import io.sentry.okhttp.SentryOkHttpInterceptor

private val client = OkHttpClient.Builder()
  .eventListener(SentryOkHttpEventListener(MyEventListener()))
  .addInterceptor(SentryOkHttpInterceptor(CustomBeforeSpanCallback()))
  .build()
```

## [HTTP Client Errors](https://docs.sentry.io/platforms/java/guides/spring-boot/tracing/instrumentation/okhttp.md#http-client-errors)

This feature automatically captures HTTP client errors (like bad response codes) as error events and reports them to Sentry. The error event will contain the `request` and `response` data, including the `url`, `status_code`, and so on.

This feature is enabled by default and can be disabled by setting the `captureFailedRequests` option to `false`:

```kotlin
import okhttp3.OkHttpClient
import io.sentry.okhttp.SentryOkHttpEventListener
import io.sentry.okhttp.SentryOkHttpInterceptor

private val client = OkHttpClient.Builder()
  .eventListener(SentryOkHttpEventListener())
  .addInterceptor(SentryOkHttpInterceptor(captureFailedRequests = false))
  .build()
```

By default, only HTTP client errors with a response code between `500` and `599` are captured as error events, but you can change this behavior by setting the `failedRequestStatusCodes` option:

```kotlin
import okhttp3.OkHttpClient
import io.sentry.okhttp.SentryOkHttpEventListener
import io.sentry.okhttp.SentryOkHttpInterceptor
import io.sentry.HttpStatusCodeRange

private val client = OkHttpClient.Builder()
  .eventListener(SentryOkHttpEventListener())
  .addInterceptor(SentryOkHttpInterceptor(
    captureFailedRequests = true,
    failedRequestStatusCodes = listOf(HttpStatusCodeRange(400, 599))))
  .build()
```

HTTP client errors from every target (`.*` regular expression) are automatically captured, but you can change this behavior by setting the `failedRequestTargets` option with either a regular expression or a plain `String`. A plain string must contain at least one of the items from the list. Plain strings don't have to be full matches, meaning the URL of a request is matched when it contains a string provided through the option.

```kotlin
import okhttp3.OkHttpClient
import io.sentry.okhttp.SentryOkHttpEventListener
import io.sentry.okhttp.SentryOkHttpInterceptor
import io.sentry.HttpStatusCodeRange

private val client = OkHttpClient.Builder()
  .eventListener(SentryOkHttpEventListener())
  .addInterceptor(SentryOkHttpInterceptor(
    captureFailedRequests = true,
    failedRequestTargets = listOf("myapi.com")))
  .build()
```

By default, error events won't contain any PII data, such as `Headers` and `Cookies`, but you can change this behavior by setting the `sendDefaultPii` option to `true`:

```kotlin
Sentry.init { options ->
  options.isSendDefaultPii = true
}
```

HTTP client errors sent to Sentry are searchable and you can set alerts on them if you use the `http.url` and `http.status_code` properties. Learn more in our full [Searchable Properties](https://docs.sentry.io/concepts/search/searchable-properties.md) documentation.

### [Customize or Drop the Error Event](https://docs.sentry.io/platforms/java/guides/spring-boot/tracing/instrumentation/okhttp.md#customize-or-drop-the-error-event)

The captured error event can be customized or dropped with a `BeforeSendCallback`:

```kotlin
import io.sentry.Sentry
import io.sentry.SentryOptions.BeforeSendCallback
import okhttp3.Request
import okhttp3.Response
import io.sentry.TypeCheckHint.OKHTTP_REQUEST
import io.sentry.TypeCheckHint.OKHTTP_RESPONSE

Sentry.init { options ->
  // Add a callback that will be used before the event is sent to Sentry.
  // With this callback, you can modify the event or, when returning null, also discard the event.
  options.beforeSend = BeforeSendCallback { event, hint ->
    val request = hint.getAs(OKHTTP_REQUEST, Request::class.java)
    val response = hint.getAs(OKHTTP_RESPONSE, Response::class.java)

    // customize or drop the event
    event
  }
}
```
