The Sentry Native SDK is intended for C and C++. However, since it builds as a dynamic library and exposes C-bindings, it can be used by any language that supports interoperability with C, such as the Foreign Function Interface (FFI).

Sentry also offers higher-level SDKs for platforms with built-in support for native crashes:

In case you would like to integrate Sentry into a third-party framework directly without using the Native SDK, see the following resources:

Integrating the SDK

The Native SDK currently supports Windows, macOS, Linux, and Android.

Building the SDK

To build the SDK, download the latest release of the SDK from the Releases page. The SDK is managed as a CMake project, which additionally supports several configuration options, such as the backend to use.

For example, CMake can be used like this (on macOS):

# configure the cmake build into the `build` directory, with crashpad (on macOS)
$ cmake -B build -D SENTRY_BACKEND=crashpad
# build the project
$ cmake --build build --parallel
# install the resulting artifacts into a specific prefix
$ cmake --install build --prefix install
# which will result in the following (on macOS):
$ exa --tree install
├── bin
│  └── crashpad_handler
├── include
│  └── sentry.h
└── lib
   ├── libsentry.dylib
   └── libsentry.dylib.dSYM

Connecting the SDK to Sentry

After completing the project setup in Sentry, it shows the Data Source Name (DSN). It looks similar to a standard URL, and contains all configuration for the SDK.

Import and initialize the Sentry SDK early in your application setup:

#include <sentry.h>

int main(void) {
  sentry_options_t *options = sentry_options_new();
  sentry_options_set_dsn(options, "___PUBLIC_DSN___");

  /* ... */

  // make sure everything flushes

Alternatively, the DSN can be passed as SENTRY_DSN environment variable during runtime. This can be especially useful for server applications.

Verifying Your Setup

Now that SDK setup is complete, verify that all configuration is correct. Start by capturing a manual event:

  /*   level */ SENTRY_LEVEL_INFO,
  /*  logger */ "custom",
  /* message */ "It works!"

Once the event is captured, it will show up on the Sentry dashboard.

Capturing Events

The Native SDK exposes a Value API to construct values like Exceptions, User objects, Tags, and even entire Events. There are several ways to create an event.

Manual Events

To create and capture a manual event, follow these steps:

  1. Create an event value using sentry_value_new_event. This internally creates an object value and initializes it with common event attributes, like a timestamp and event_id.
  2. Add custom attributes to the event, like a message or an exception.
  3. Send the event to Sentry by invoking sentry_capture_event.

In a more complex example, it looks like this:

sentry_value_t event = sentry_value_new_event();
sentry_value_set_by_key(event, "message", sentry_value_new_string("Hello!"));

sentry_value_t screen = sentry_value_new_object();
sentry_value_set_by_key(screen, "width", sentry_value_new_int32(1920));
sentry_value_set_by_key(screen, "height", sentry_value_new_int32(1080));

sentry_value_t extra = sentry_value_new_object();
sentry_value_set_by_key(extra, "screen_size", screen);

sentry_value_set_by_key(event, "extra", extra);

For the full list of supported values, see Event Payloads and linked documents.


To capture an error or exception condition, create events containing an exception object. It needs to contain at least a value and type:

#include <sentry.h>

sentry_value_t exc = sentry_value_new_object();
sentry_value_set_by_key(exc, "type", sentry_value_new_string("Exception"));
sentry_value_set_by_key(exc, "value", sentry_value_new_string("Error message."));

sentry_value_t event = sentry_value_new_event();
sentry_value_set_by_key(event, "exception", exc);

This exception does not contain a stack trace, which must be added separately.

Message Events

To simplify creating events, there are shorthand functions that construct prepopulated event objects. The most important one is sentry_value_new_message_event. The logger and message parameters are each optional.

sentry_value_t event = sentry_value_new_message_event(
  /*   level */ SENTRY_LEVEL_INFO,
  /*  logger */ "custom",
  /* message */ "It works!"

Uploading Debug Information

To allow Sentry to fully process native crashes and provide you with symbolicated stack traces, you need to upload Debug Information Files (sometimes also referred to as Debug Symbols or just Symbols). We recommend uploading debug information during your build or release process.

For all libraries where you’d like to receive symbolication, you need to provide debug information. This includes dependencies and operating system libraries. If you are not sure which files are required, go to Project Settings > Processing Issues, which shows a list of all the necessary files and instructions to retrieve them.

In addition to Debug Information Files, Sentry needs Call Frame Information (CFI) to extract accurate stack traces from minidumps of optimized release builds. CFI is usually part of the executables and not copied to debug symbols. Unless you are uploading Breakpad symbols, be sure to also include the binaries when uploading files to Sentry.

For more information on uploading debug information and their supported formats, see Debug Information Files.


A release is a version of your code that you deploy to an environment. When you give Sentry information about your releases, you unlock many new features:

  • Determine the issue and regressions introduced in a new release
  • Predict which commit caused an issue and who is likely responsible
  • Resolve issues by including the issue number in your commit message
  • Receive email notifications when your code gets deployed

After configuring your SDK, setting up releases is a 2-step process:

  1. Create Release and Associate Commits
  2. Tell Sentry When You Deploy a Release

For more information, see Releases Are Better With Commits.

To configure the SDK to send release information, set the release during initialization:

  sentry_options_t *options = sentry_options_new();
  sentry_options_set_release(options, "my-unique-release-1.0.0");


Sentry supports additional context with events. Often this context is shared among any issue captured in its lifecycle, and includes the following components:

Structured Contexts

Structured contexts are typically set automatically.


Information about the current actor.


Key/value pairs which generate breakdown charts and search filters.


An event’s severity.


A value used for grouping events into issues.

Unstructured Extra Data

Arbitrary unstructured data which the Sentry SDK stores with an event sample.

Context information is attached to every event until explicitly removed or overwritten.

Extra Context

In addition to the structured contexts that Sentry understands, you can send arbitrary key/value pairs of data which the Sentry SDK will store alongside the event. These are not indexed, and the Sentry SDK uses them to add additional information about what might be happening.

sentry_set_extra takes the name of the extra value as first parameter, and the value as sentry_value_t as second parameter:

sentry_value_t screen = sentry_value_new_object();
sentry_value_set_by_key(screen, "width", sentry_value_new_int32(1920));
sentry_value_set_by_key(screen, "height", sentry_value_new_int32(1080));
sentry_set_extra("screen_size", screen);

Capturing the User

Sending users to Sentry will unlock many features, primarily the ability to drill down into the number of users affecting an issue, as well as to get a broader sense about the quality of the application.

sentry_value_t user = sentry_value_new_object();
sentry_value_set_by_key(user, "id", sentry_value_new_int32(42));
sentry_value_set_by_key(user, "username", sentry_value_new_string("John Doe"));

Users consist of a few critical pieces of information which are used to construct a unique identity in Sentry. Each of these is optional, but one must be present for the Sentry SDK to capture the user:


Your internal identifier for the user.


The user’s username. Generally used as a better label than the internal ID.


An alternative, or addition, to a username. Sentry is aware of email addresses and can show things like Gravatars, unlock messaging capabilities, and more.


The IP address of the user. If the user is unauthenticated, providing the IP address will suggest that this is unique to that IP. If available, we will attempt to pull this from the HTTP request data.

Additionally, you can provide arbitrary key/value pairs beyond the reserved names, and the Sentry SDK will store those with the user.

Tagging Events

Tags are key/value pairs assigned to events that can be used for breaking down issues or quick access to finding related events.

sentry_set_tag("server_name", "caroline");

For more information, see the Tagging Events section in Context.

Setting the Level

You can set the severity of an event to one of five values (sorted from most severe to least severe): fatal, error, warning, info, and debug. The default level is error.


Setting the Fingerprint

Sentry uses a fingerprint to decide how to group errors into issues.

For some very advanced use cases, you can override the Sentry default grouping using the fingerprint attribute. In supported SDKs, this attribute can be passed with the event information and should be an array of strings.

If you wish to append information, thus making the grouping slightly less aggressive, you can do that as well by adding the special string {{default}} as one of the items.

For code samples, see Grouping & Fingerprints.

For more information, see Aggregate Errors with Custom Fingerprints.

Advanced Usage

Advanced Configuration

The Native SDK sets the options when you first initialize the SDK:

sentry_options_t *options = sentry_options_new();

sentry_options_set_environment(options, "Production");
sentry_options_set_release(options, "5fd7a6cd");
sentry_options_set_debug(options, 1);


For more information, see:

To receive more information on actions leading up to an exception or crash, the SDK can record breadcrumbs that are automatically added to every event. The most recent breadcrumbs are kept in a buffer.

You can manually add breadcrumbs using sentry_add_breadcrumb:

#include <sentry.h>

sentry_value_t crumb = sentry_value_new_breadcrumb("default", "Authenticated user");
sentry_value_set_by_key(crumb, "category", sentry_value_new_string("auth"));
sentry_value_set_by_key(crumb, "level", sentry_value_new_string("info"));

For more information, see:

Filter Events & Custom Logic

Sentry exposes a before_send callback which can be used to filter out information or add additional context to the event object. The callback must conform to the sentry_event_function_t signature.

#include <sentry.h>

sentry_value_t strip_sensitive_data(sentry_value_t event, void *hint) {
  /* modify event here or return NULL to discard the event */
  return event;

int main(void) {
  sentry_options_t *options = sentry_options_new();
  sentry_options_set_before_send(options, strip_sensitive_data);

  /* ... */

The callback is executed in the same thread as the call to sentry_capture_event. Work performed by the function may thus block the executing thread. For this reason, consider avoiding heavy work in before_send.

For more information, see:


The Native SDK uses Transports to send event payloads to Sentry. The default transport depends on the target platform:

  • Linux: Curl
  • macOS: Curl

To specify a custom transport, use the sentry_options_set_transport function and supply a transport that implements the sentry_transport_t interface. To simplify using a single function, one might use the sentry_new_function_transport function:

#include <sentry.h>

void custom_transport(sentry_value_t event, void *data) {
   * Send the event here. If the transport requires state, such as an HTTP
   * client object or request queue, it can be specified in the `data`
   * parameter when configuring the transport. It will be passed as second
   * argument to this function.

int main(void) {
  void *transport_data = 0;

  sentry_options_t *options = sentry_options_new();
    sentry_new_function_transport(custom_transport, transport_data));

  /* ... */

The transport is invoked in the same thread as the call to sentry_capture_event. Consider to offload network communication to a background thread or thread pool to avoid blocking execution.


Integrations extend the functionality of the SDK for some common frameworks and libraries. Similar to plugins, they extend the functionality of the Sentry SDK.

The Native SDK can use different backends that are responsible for capturing crashes. The backend is configured at build-time, using the SENTRY_BACKEND CMake option.

The crashpad backend is used by default on Windows and macOS, whereas Linux and Android use the inproc in-process backend by default.

Google Crashpad

Crashpad is an open-source multiplatform crash reporting system written in C++ by Google. It supports macOS, Windows, and Linux (limited), and features an uploader to submit minidumps to a configured URL right when the process crashes.

To use the Crashpad backend with the Native SDK, configure the CMake build with the SENTRY_BACKEND=crashpad option. This will automatically create a crashpad_handler executable alongside the sentry library.

$ cmake -B build -D SENTRY_BACKEND=crashpad

The SDK will automatically look for a crashpad_handler executable in the same directory as the running application. It will also use the .sentry-native directory as its database by default, relative to the current working directory of your application. This location temporarily hosts Minidumps before they are uploaded to Sentry.

Both of these paths can be customized like this:

sentry_options_t *options = sentry_options_new();
sentry_options_set_handler_path(options, "path/to/crashpad_handler");
sentry_options_set_database_path(options, "sentry-db-directory");

The crashpad handler executable must be shipped alongside your application so that it can be launched when initializing the SDK. The path is evaluated relative to the current working directory at runtime.

Event Attachments (Preview)

Besides the Minidump file, Sentry can optionally store additional files uploaded in the same request, such as log files.

The organization and project setting Store Native Crash Reports also enables storage of the original minidump files. For data privacy reasons, this setting is by default disabled. Raw minidumps are deleted permanently with their issues or after 30 days.

To add an attachment, the path to the file has to be configured when initializing the SDK. It will monitor the file and upload it along with any event or crash that is sent to Sentry:

sentry_options_add_attachment(options, "log", "/var/server.log");