---
title: .NET agent API
source: https://docs.newrelic.com/docs/apm/agents/net-agent/net-agent-api/net-agent-api
---

New Relic's .NET agent includes an API that allows you to extend the agent's standard functionality. For example, you can use the .NET agent API to:

-   Customize your app name
-   Create custom transaction parameters
-   Report custom errors and metrics

You can also customize some of the .NET agent's default behavior by adjusting [configuration settings](https://docs.newrelic.com/docs/agents/net-agent/configuration/net-agent-configuration) or using [custom instrumentation](https://docs.newrelic.com/docs/agents/net-agent/custom-instrumentation/introduction-net-custom-instrumentation).

## Requirements

To use the .NET agent API, make sure you have the [latest .NET agent release](https://docs.newrelic.com/docs/release-notes/agent-release-notes/net-release-notes). Then, add a reference to the agent in your project using one of the two options below:

-   Add a reference to `NewRelic.Api.Agent.dll` to your project.

    OR

-   View and download the API package from the [NuGet Package Library](https://www.nuget.org/packages/NewRelic.Agent.Api/).

## Notes on Dependency Injection

If you consume the agent API through `Microsoft.Extensions.DependencyInjection` (or a similar container), there are two pitfalls that will silently disable your custom instrumentation without producing any error. Both stem from the fact that [`IAgent`](https://docs.newrelic.com/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#IAgent) is a long-lived handle, but [`CurrentTransaction`](https://docs.newrelic.com/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#ITransaction) and [`CurrentSpan`](https://docs.newrelic.com/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#ISpan) are request-scoped views that must be re-read on every call.

### Register `IAgent` lazily, not eagerly

[`GetAgent()`](https://docs.newrelic.com/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#GetAgent) must be called **after** the profiler has finished attaching. If you resolve it eagerly while the DI container is being built, you may cache the no-op placeholder the API returns before the agent is live, leaving the application with a silently disabled API for the lifetime of the process. Use a factory lambda so the call is deferred to first resolution:

```cs
// ❌ Eager — may capture the no-op placeholder
builder.Services.AddSingleton<IAgent>(NewRelic.Api.Agent.NewRelic.GetAgent());

// ✅ Lazy — GetAgent() runs on first resolution, after the profiler is ready
builder.Services.AddSingleton<IAgent>(_ => NewRelic.Api.Agent.NewRelic.GetAgent());
```

### Do not cache `ITransaction` or `ISpan` in fields

`IAgent` itself is safe to store, but `CurrentTransaction` and `CurrentSpan` must be read fresh each time you use them. Capturing them in a constructor or field binds your service to whichever request happened to be in flight when the field was first assigned. Every subsequent call then writes attributes, errors, and events to a transaction that has already ended, and the data never appears on the transactions you are actually looking at.

```cs
// ❌ Captures one request's transaction forever
public class BuggyService
{
    private readonly ITransaction _transaction;
    public BuggyService(IAgent agent) => _transaction = agent.CurrentTransaction;
}

// ✅ Fetch per-call
public class WorkService
{
    private readonly IAgent _agent;
    public WorkService(IAgent agent) => _agent = agent;

    public void DoWork()
    {
        var transaction = _agent.CurrentTransaction;
        transaction.AddCustomAttribute("key", "value");
    }
}
```

For a complete, runnable walkthrough, including compile-checked anti-pattern examples, see the [api-dependency-injection example](https://github.com/newrelic/newrelic-dotnet-examples/tree/main/api-dependency-injection) in the `newrelic-dotnet-examples` repository.

## List of API calls

The following list contains the different calls you can make with the API, including syntax, requirements, functionality, and examples:

**DisableBrowserMonitoring**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.DisableBrowserMonitoring([boolean $override])
```

Disable automatic injection of browser monitoring snippet on specific pages.

### Requirements

* Compatible with all agent versions.
* Must be called inside a [transaction](/docs/glossary/glossary/#transaction).

### Description

Add this call to disable the **automatic** injection of [<InlinePopover type="browser"/>](/docs/browser/new-relic-browser/getting-started/new-relic-browser) scripts on specific pages. You can also add an optional override to disable **both** manual and automatic injection. In either case, put this API call as close as possible to the top of the view in which you want browser disabled.

<Callout variant="tip">
  Compare [`GetBrowserTimingHeader()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#GetBrowserTimingHeader), which **adds** the browser script to the page.
</Callout>

### Parameters

<table>
  <thead>
    <tr>
      <th width="25%">
        Parameter
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `$override`

        _boolean_
      </td>

      <td>
        Optional. When `true`, disables all injection of browser scripts. This flag affects both manual and automatic injection. This also overrides the [`GetBrowserTimingHeader()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#GetBrowserTimingHeader) call.
      </td>
    </tr>
  </tbody>
</table>

### Examples

#### Disable automatic injection

This example disables only the **automatic** injection of the snippet:

```cs
NewRelic.Api.Agent.NewRelic.DisableBrowserMonitoring();
```

#### Disable automatic and manual injection

This example disables **both** automatic and manual injection of the snippet:

```cs
NewRelic.Api.Agent.NewRelic.DisableBrowserMonitoring(true);
```

````

**GetAgent**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.GetAgent()
```

Get access to the agent via the `IAgent` interface.

### Requirements

* Agent version 8.9 or higher.
* Compatible with all app types.

### Description

Get access to agent API methods via the [`IAgent`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#IAgent) interface.

### Return values

An implementation of [IAgent](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#IAgent) providing access to the IAgent API.

### Examples

```cs
IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent();
```

````

**GetBrowserTimingHeader**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.GetBrowserTimingHeader();
NewRelic.Api.Agent.NewRelic.GetBrowserTimingHeader(string nonce);
```

Generate a browser monitoring HTML snippet to instrument end-user browsers.

### Requirements

* Compatible with all agent versions.
* Must be called inside a [transaction](/docs/accounts-partnerships/education/getting-started-new-relic/glossary#transaction).

### Description

Returns an HTML snippet used to enable <InlinePopover type="browser"/>. The snippet instructs the browser to fetch a small JavaScript file and start the page timer. You can then insert the returned snippet into the header of your HTML webpages. For more information, see [Adding apps to browser monitoring](/docs/browser/new-relic-browser/installation-configuration/adding-apps-new-relic-browser).

<Callout variant="tip">
  Compare [`DisableBrowserMonitoring()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#DisableBrowserMonitoring), which **disables** the browser script on a page.
</Callout>

### Parameters

<table>
  <thead>
    <tr>
      <th width="25%">
        Parameter
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `nonce`

        _string_
      </td>

      <td>
        The per-request, cryptographic nonce used by Content Security Policy policies.
      </td>
    </tr>
  </tbody>
</table>

<Callout variant="tip">
  This API call requires updates to security allow lists. For more information about Content Security Policy (CSP) considerations, visit the [browser monitoring compatibility and requirements](/docs/browser/new-relic-browser/getting-started/compatibility-requirements-browser-monitoring) page.
</Callout>

### Return values

An HTML string to be embedded in a page header.

### Examples

<CollapserGroup>
  <Collapser
    id=""
    title="With ASPX"
  >
    ```aspnet
    <html>
    <head>
        <%= NewRelic.Api.Agent.NewRelic.GetBrowserTimingHeader()%>
        ...
    </head>
    <body>
    ...
    ```

    ```aspnet
    <html>
    <head>
        <%= NewRelic.Api.Agent.NewRelic.GetBrowserTimingHeader("YOUR_NONCE_VALUE")%>
        ...
    </head>
    <body>
    ...
    ```
  </Collapser>

  <Collapser
    id=""
    title="With Razor"
  >
    ```cshtml
    <!DOCTYPE html>
    <html lang="en">
    <head>
        @Html.Raw(NewRelic.Api.Agent.NewRelic.GetBrowserTimingHeader())
        ...
    </head>
    <body>
    ...
    ```

    ```cshtml
    <!DOCTYPE html>
    <html lang="en">
    <head>
        @Html.Raw(NewRelic.Api.Agent.NewRelic.GetBrowserTimingHeader("YOUR_NONCE_VALUE"))
        ...
    </head>
    <body>
    ...
    ```
  </Collapser>

  <Collapser
    id=""
    title="With Blazor"
  >
    <Callout variant="important">
      This API is not supported for Blazor Webassembly, because the agent is unable to instrument Webassembly code.  The following examples are for Blazor Server applications only.  Use the [copy-paste method](/docs/browser/browser-monitoring/installation/install-browser-monitoring-agent/#copy-paste) of adding the browser agent to Blazor Webassembly pages.
    </Callout>

    <Callout variant="important">
      This API can not be placed in a `<HeadContent>` element of a `.razor` page.  Instead, it should be called from `_Layout.cshtml` or an equivalent layout file.

      ```cshtml
      <!DOCTYPE html>
      <html lang="en">
      <head>
          @Html.Raw(NewRelic.Api.Agent.NewRelic.GetBrowserTimingHeader())
          ...
      </head>
      <body>
      ...
      ```

      ```cshtml
      <!DOCTYPE html>
      <html lang="en">
      <head>
          @Html.Raw(NewRelic.Api.Agent.NewRelic.GetBrowserTimingHeader("YOUR_NONCE_VALUE"))
          ...
      </head>
      <body>
      ...
      ```
    </Callout>
  </Collapser>
</CollapserGroup>

````

**GetLinkingMetadata**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.GetLinkingMetadata();
```

Returns key/value pairs which can be used to link traces or entities.

### Requirements

* Agent version 8.19 or higher.
* Compatible with all app types.

### Description

The dictionary of key/value pairs returned includes items used to link traces and entities in the APM product. It will only contain items with meaningful values. For instance, if distributed tracing is disabled, `trace.id` will not be included.

### Return values

`Dictionary <string, string>()` returned includes items used to link traces and entities in the APM product.

### Examples

```cs
NewRelic.Api.Agent.IAgent Agent = NewRelic.Api.Agent.NewRelic.GetAgent();
var linkingMetadata = Agent.GetLinkingMetadata();
foreach (KeyValuePair<string, string> kvp in linkingMetadata)
{
    Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
```

````

**IAgent**

### Syntax

````cs
public interface IAgent
```

Provides access to agent artifacts and methods, such as the currently executing transaction.

### Requirements

* Agent version 8.9 or higher.
* Compatible with all app types.

### Description

Provides access to agent artifacts and methods, such as the currently executing transaction. To obtain a reference to `IAgent`, use [`GetAgent`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#GetAgent).

### Properties

<table>
  <thead>
    <tr>
      <th width="25%">
        Name
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        CurrentTransaction
      </td>

      <td>
        Property providing access to the currently executing transaction via the [ITransaction](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#ITransaction) interface. Must be called inside a [transaction](/docs/accounts-partnerships/education/getting-started-new-relic/glossary#transaction).
      </td>
    </tr>

    <tr>
      <td>
        CurrentSpan
      </td>

      <td>
        Property providing access to the currently executing span via the [ISpan](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#ISpan) interface.
      </td>
    </tr>
  </tbody>
</table>

### Examples

```cs
IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent();
ITransaction transaction = agent.CurrentTransaction;
```

````

**ITransaction**

### Syntax

````cs
public interface ITransaction
```

Provides access to transaction-specific methods in the New Relic API.

### Description

Provides access to transaction-specific methods in the New Relic .NET agent API. To obtain a reference to `ITransaction`, use the current transaction method available on [`IAgent`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#IAgent).

The following methods are available on `ITransaction`:

<table>
  <thead>
    <tr>
      <th>
        Name
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td class="children-nowrap">
        `InsertDistributedTraceHeaders`
      </td>

      <td>
        Adds distributed tracing data to an outgoing request (see below for more details).
      </td>
    </tr>

    <tr>
      <td class="children-nowrap">
        `AcceptDistributedTraceHeaders`
      </td>

      <td>
        Accepts incoming distributed tracing data from another service (see below for more details).
      </td>
    </tr>

    <tr>
      <td class="children-nowrap">
        `AddCustomAttribute`
      </td>

      <td>
        Add contextual information from your application to the current transaction in form of attributes (see below for more details).
      </td>
    </tr>

    <tr>
      <td class="children-nowrap">
        `CurrentSpan`
      </td>

      <td>
        Provides access to the currently executing [span](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#ISpan), which provides access to span-specific methods in the New Relic API (see below for more details).
      </td>
    </tr>

    <tr>
      <td class="children-nowrap">
        `SetUserId`
      </td>

      <td>
        Associates a user ID to the current transaction (see below for more details).
      </td>
    </tr>

    <tr>
      <td class="children-nowrap">
        `RecordDatastoreSegment`
      </td>

      <td>
        Allows an unsupported datastore to be instrumented (see below for more details).
      </td>
    </tr>
  </tbody>
</table>

<CollapserGroup>
  <Collapser
    id="InsertDistributedTraceHeaders"
    title="InsertDistributedTraceHeaders"
  >
    ### Syntax

    ```cs
    void InsertDistributedTraceHeaders(carrier, setter)
    ```

    Adds [distributed tracing](/docs/apm/agents/net-agent/configuration/distributed-tracing-net-agent/#manual-instrumentation) data to an outbound message to another instrumented service.

    ### Description

    `ITransaction.InsertDistributedTraceHeaders` modifies the carrier object that is passed in by adding W3C Trace Context headers and New Relic Distributed Trace headers. The New Relic headers can be disabled with `<distributedTracing excludeNewrelicHeader="true" />` in the config.

    ### Parameters

    <table>
      <thead>
        <tr>
          <th>
            Name
          </th>

          <th>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `carrier`

            _&lt;T>_
          </td>

          <td>
            Required. A key/value pair store where distributed tracing data is inserted. This needs to exist in whatever message object is being passed from the calling service to the called service, via whatever transport is being used.  For example, for Azure Service Bus messages, the `ServiceBusMessage` type has an [`ApplicationProperties` property](https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.servicebusmessage.applicationproperties?view=azure-dotnet#azure-messaging-servicebus-servicebusmessage-applicationproperties) which is an `IDictionary<string,object>`.
            When you want to implement custom distributed tracing for an uninstrumented communications channel (e.g. a message queue), you need to find out what key/value pair storage (carrier) option exists for that channel. 
          </td>
        </tr>

        <tr>
          <td>
            `setter`

            _Action&lt;T, string, string>_
          </td>

          <td>
            Required. A user-defined Action to insert tracing data into the carrier. See example below.
          </td>
        </tr>
      </tbody>
    </table>

    ### Usage considerations

    * [Distributed tracing must be enabled](/docs/agents/net-agent/configuration/net-agent-configuration#distributed_tracing).
    * This API can only be used within the context of an existing [transaction](/docs/apm/agents/net-agent/custom-instrumentation/introduction-net-custom-instrumentation/#new-existing).

    ### Example

    You can find a complete example that you can build and run to demonstrate the use of this API [here](https://github.com/newrelic/newrelic-dotnet-examples/tree/main/custom-distributed-tracing).

    ```cs
    // Get a reference to the agent, which lets you get a reference to the current transaction
    IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent();
    ITransaction currentTransaction = agent.CurrentTransaction;

    // In this example, we are using Azure Service Bus.  The `ServiceBusMessage` type has an `ApplicationProperties` property for custom key/value pairs.

    // Create the outbound message
    ServiceBusMessage message = new ("Hello, world!");

    // Define the setter Action.  The `ApplicationProperties` dictionary is the trace data carrier.
    var setter = new Action<ServiceBusMessage, string, string>((carrier, key, value) => { carrier.ApplicationProperties?.Set(key, value); });

    // Call the API to add the distributed tracing data to the message
    currentTransaction.InsertDistributedTraceHeaders(message, setter);

    // Send the message
    ```
  </Collapser>

  <Collapser
    id="AcceptDistributedTraceHeaders"
    title="AcceptDistributedTraceHeaders"
  >
    ### Syntax

    ```cs
    void AcceptDistributedTraceHeaders(carrier, getter, transportType)
    ```

    Accepts [distributed tracing](/docs/apm/agents/net-agent/configuration/distributed-tracing-net-agent/#manual-instrumentation) data from an inbound message from another instrumented service.

    ### Description

    `ITransaction.AcceptDistributedTraceHeaders` is used to link the spans in a trace by accepting a payload generated by [`InsertDistributedTraceHeaders`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#InsertDistributedTraceHeaders) or generated by some other W3C Trace Context compliant tracer. This method accepts the key/value store from an incoming request, looks for W3C Trace Context data, and if not found, falls back to New Relic distributed trace data.

    ### Parameters

    <table>
      <thead>
        <tr>
          <th>
            Name
          </th>

          <th>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `carrier`

            _&lt;T>_
          </td>

          <td>
            Required. A key/value pair store where distributed tracing data was inserted by the calling service. This needs to exist in whatever message object is being passed from the calling service to the called service, via whatever transport is being used.  For example, for Azure Service Bus messages, the `ServiceBusReceivedMessage` type has an [`ApplicationProperties` property](https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.servicebusmessage.applicationproperties?view=azure-dotnet#azure-messaging-servicebus-servicebusmessage-applicationproperties) which is an `IDictionary<string,object>`.
            When you want to implement custom distributed tracing for an uninstrumented communications channel (e.g. a message queue), you need to find out what key/value pair storage (carrier) option exists for that channel.
          </td>
        </tr>

        <tr>
          <td>
            `getter`

            _Func&lt;T, string, IEnumerable&lt;string>>_
          </td>

          <td>
            Required. A user-defined Func to extract tracing data from the carrier. See example below.
          </td>
        </tr>

        <tr>
          <td>
            `transportType`

            _TransportType enum_
          </td>

          <td>
            Required. Describes the transport of the incoming payload (for example `TransportType.Queue`). The full list is defined [here](https://github.com/newrelic/newrelic-dotnet-agent/blob/main/src/Agent/NewRelic.Api.Agent/Constants.cs).
          </td>
        </tr>
      </tbody>
    </table>

    ### Usage considerations

    * [Distributed tracing must be enabled](/docs/agents/net-agent/configuration/net-agent-configuration#distributed_tracing).
    * This API can only be used within the context of an existing [transaction](/docs/apm/agents/net-agent/custom-instrumentation/introduction-net-custom-instrumentation/#new-existing).
    * `AcceptDistributedTraceHeaders` will be ignored if `InsertDistributedTraceHeaders` or `AcceptDistributedTraceHeaders` has already been called for this transaction.

    ### Example

    You can find a complete example that you can build and run to demonstrate the use of this API [here](https://github.com/newrelic/newrelic-dotnet-examples/tree/main/custom-distributed-tracing)

    ```cs
    // Get a reference to the agent, which lets you get a reference to the current transaction
    IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent();
    ITransaction currentTransaction = agent.CurrentTransaction;

    // In this example, we are using Azure Service Bus.  The `ServiceBusMessage` type has an `ApplicationProperties` property for custom key/value pairs.

    // Recieve an incoming message.  Assume that `receiver` is a previously-configured `ServiceBusReceiver`
    ServiceBusReceivedMessage message = await receiver.ReceiveMessageAsync();

    // Define the getter Func.  The `ApplicationProperties` dictionary is the trace data carrier.
    IEnumerable<string> Getter(IDictionary<string, object> carrier, string key)
    {
      var data = new List<string>();
      if (carrier == null)
      {
        return data;
      }
      object value;
      if (applicationProperties.TryGetValue(key, out value))
      {
        if (value != null)
        {
          data.Add(value.ToString());
        }
      }
      return data;
    }

    // Call the API to accept the distributed tracing data from the message
    currentTransaction.AcceptDistributedTraceHeaders(message.ApplicationProperties, Getter, TransportType.Queue);

    ```
  </Collapser>

  <Collapser
    id="ITransaction.AddCustomAttribute"
    title="AddCustomAttribute"
  >
    ### Syntax

    ```cs
    ITransaction AddCustomAttribute(string key, object value)
    ```

    Adds contextual information about your application to the current transaction in the form of [attributes](/docs/using-new-relic/welcome-new-relic/get-started/glossary#attribute).

    This method requires .NET agent version and .NET agent API [version 8.24.244.0](/docs/release-notes/agent-release-notes/net-release-notes/net-agent-8242440) or higher. It replaced the deprecated `AddCustomParameter`.

    ### Parameters

    <table>
      <thead>
        <tr>
          <th>
            Parameter
          </th>

          <th>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `key`

            _string_
          </td>

          <td>
            Identifies the information being reported. Also known as the name.

            * Empty keys are not supported.
            * Keys are limited to 255-bytes. Attributes with keys larger than 255-bytes will be ignored.
          </td>
        </tr>

        <tr>
          <td>
            `value`

            _object_
          </td>

          <td>
            The value being reported.

            **Note**: `null` values will not be recorded.
          </td>
        </tr>
      </tbody>
    </table>

    <table>
      <thead>
        <tr>
          <th>
            .NET type
          </th>

          <th>
            How the value will be represented
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `byte`, `Int16`, `Int32`, `Int64`

            `sbyte`, `UInt16`, `UInt32`, `UInt64`
          </td>

          <td>
            As an integral value.
          </td>
        </tr>

        <tr>
          <td>
            `float`, `double`, `decimal`
          </td>

          <td>
            A decimal-based number.
          </td>
        </tr>

        <tr>
          <td>
            `string`
          </td>

          <td>
            A string truncated after 255-bytes.

            Empty strings are supported.
          </td>
        </tr>

        <tr>
          <td>
            `bool`
          </td>

          <td>
            True or false.
          </td>
        </tr>

        <tr>
          <td>
            `DateTime`
          </td>

          <td>
            A string representation following the ISO-8601 format, including time zone information:

            Example: `2020-02-13T11:31:19.5767650-08:00`
          </td>
        </tr>

        <tr>
          <td>
            `TimeSpan`
          </td>

          <td>
            A decimal-based number representing number of seconds.
          </td>
        </tr>

        <tr>
          <td>
            `arrays`, `Lists`, and other `IEnumerable` types
          </td>

          <td>
            Serialized as a JSON array. Individual elements follow the same type conversion rules above. Null elements are filtered out. Empty arrays and arrays containing only null values are not recorded. Requires .NET agent version 10.50.0 or later.
          </td>
        </tr>

        <tr>
          <td>
            everything else
          </td>

          <td>
            The `ToString()` method will be applied. Custom types must have an implementation of `Object.ToString()` or they will throw an exception.
          </td>
        </tr>
      </tbody>
    </table>

    ### Returns

    A reference to the current transaction.

    ### Usage considerations

    For details about supported data types, see [Custom attributes](/docs/agents/net-agent/attributes/custom-attributes).

    ### Example

    ```cs
    IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent();
    ITransaction transaction = agent.CurrentTransaction;
    transaction.AddCustomAttribute("customerName","Bob Smith")
        .AddCustomAttribute("currentAge",31)
        .AddCustomAttribute("birthday", new DateTime(2000, 02, 14))
        .AddCustomAttribute("waitTime", TimeSpan.FromMilliseconds(93842))
        .AddCustomAttribute("colors", new[] { "red", "green", "blue" })
        .AddCustomAttribute("ids", new List<int> { 1, 2, 3 });
    ```
  </Collapser>

  <Collapser
    id="CurrentSpan"
    title="CurrentSpan"
  >
    Provides access to the currently executing [span](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#ISpan), making span-specific methods available within the New Relic API.

    ### Example

    ```cs
    IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent(); 
    ITransaction transaction = agent.CurrentTransaction; 
    ISpan currentSpan = transaction.CurrentSpan;
    ```
  </Collapser>

  <Collapser
    id="SetUserId"
    title="SetUserId"
  >
    ### Syntax

    ```cs
    ITransaction SetUserId(string userId)
    ```

    Associates a user ID with the current transaction.

    This method requires .NET agent and .NET agent API [version 10.9.0](/docs/release-notes/agent-release-notes/net-release-notes/net-agent-1090) or higher.

    ### Parameters

    <table>
      <thead>
        <tr>
          <th>
            Parameter
          </th>

          <th>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `userId`

            _string_
          </td>

          <td>
            The User Id to be associated with this transaction.

            * `null`, empty and whitespace values will be ignored.
          </td>
        </tr>
      </tbody>
    </table>

    ### Example

    ```cs
    IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent(); 
    ITransaction transaction = agent.CurrentTransaction; 
    transaction.SetUserId("BobSmith123");
    ```
  </Collapser>
  <Collapser
    id="RecordDatastoreSegment"
    title="RecordDatastoreSegment"
  >
    ### Syntax

    ```cs
    SegmentWrapper? RecordDatastoreSegment(string vendor, string model, string operation, string? commandText = null, string? host = null, string? portPathOrID = null, string? databaseName = null)
    ```

    Allows an unsupported datastore to be instrumented in the same way as the .NET agent automatically instruments its supported datastores.

    This method requires .NET agent and .NET agent API [version 10.22.0](/docs/release-notes/agent-release-notes/net-release-notes/net-agent-10-22-0/) or higher.

    ### Parameters

    <table>
      <thead>
        <tr>
          <th>
            Parameter
          </th>

          <th>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `vendor`

            _string_
          </td>

          <td>
          Datastore vendor name, such as MySQL, MSSQL, or MongoDB.
          </td>
        </tr>
        <tr>
          <td>
            `model`

            _string_
          </td>

          <td>
          Table name, or similar identifier in a non-relational datastore.
          </td>
        </tr>
        <tr>
          <td>
            `operation`

            _string_
          </td>

          <td>
          Operation being performed, such as "SELECT" or "UPDATE" for SQL databases.
          </td>
        </tr>
        <tr>
          <td>
            `commandText`

            _string?_
          </td>

          <td>
          Optional. Query, or similar descriptor in a non-relational datastore.
          </td>
        </tr>
        <tr>
          <td>
            `host`

            _string?_
          </td>

          <td>
          Optional. Server hosting the datastore.
          </td>
        </tr>
        <tr>
          <td>
            `portPathOrID`

            _string?_
          </td>

          <td>
          Optional. Port, path, or other identifier, paired with the host to aid in identifying the datastore.
          </td>
        </tr>
        <tr>
          <td>
            `databaseName`

            _string?_
          </td>

          <td>
          Optional. Datastore name or similar identifier.
          </td>
        </tr>
      </tbody>
    </table>

    ### Returns

    IDisposable segment wrapper that both creates and ends the segment automatically.

    ### Example

    ```cs
    var transaction = NewRelic.Api.Agent.NewRelic.GetAgent().CurrentTransaction;
    using (transaction.RecordDatastoreSegment(vendor, model, operation,
         commandText, host, portPathOrID, databaseName))
    {
         DatastoreWorker();
    }
    ```

  </Collapser>
</CollapserGroup>

````

**ISpan**

### Syntax

````cs
Public interface ISpan
```

Provides access to span-specific methods in the New Relic API.

### Description

Provides access to span-specific methods in the New Relic .NET agent API. To obtain a reference to `ISpan`, use:

* The `CurrentSpan` property on [`IAgent`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#IAgent) (Recommended).
* The `CurrentSpan` property on [`ITransaction`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#ITransaction).

This section contains descriptions and parameters of `ISpan` methods:

<table>
  <thead>
    <tr>
      <th>
        Name
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td class="children-nowrap">
        `AddCustomAttribute`
      </td>

      <td>
        Add contextual information from your application to the current span in form of attributes (see below for more details).
      </td>
    </tr>

    <tr>
      <td>
        `SetName`
      </td>

      <td>
        Changes the name of the current span/segment/metrics that will be reported to New Relic (see below for more details).
      </td>
    </tr>
  </tbody>
</table>

<CollapserGroup>
  <Collapser
    id="ISpan.AddCustomAttribute"
    title="AddCustomAttribute"
  >
    Adds contextual information about your application to the current span in the form of [attributes](/docs/using-new-relic/welcome-new-relic/get-started/glossary#attribute).

    This method requires .NET agent version and .NET agent API [version 8.25](/docs/release-notes/agent-release-notes/net-release-notes/net-agent-8242440) or higher.

    ### Syntax

    ```cs
    ISpan AddCustomAttribute(string key, object value)
    ```

    ### Parameters

    <table>
      <thead>
        <tr>
          <th>
            Parameter
          </th>

          <th>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `key`

            _string_
          </td>

          <td>
            Identifies the information being reported. Also known as the name.

            * Empty keys are not supported.
            * Keys are limited to 255-bytes. Attributes with keys larger than 255-bytes will be ignored.
          </td>
        </tr>

        <tr>
          <td>
            `value`

            _object_
          </td>

          <td>
            The value being reported.

            **Note**: `null` values will not be recorded.

            <table>
              <thead>
                <tr>
                  <th>
                    .NET type
                  </th>

                  <th>
                    How the value will be represented
                  </th>
                </tr>
              </thead>

              <tbody>
                <tr>
                  <td>
                    `byte`, `Int16`, `Int32`, `Int64`

                    `sbyte`, `UInt16`, `UInt32`, `UInt64`
                  </td>

                  <td>
                    As an integral value.
                  </td>
                </tr>

                <tr>
                  <td>
                    `float`, `double`, `decimal`
                  </td>

                  <td>
                    A decimal-based number.
                  </td>
                </tr>

                <tr>
                  <td>
                    `string`
                  </td>

                  <td>
                    A string truncated after 255-bytes.

                    Empty strings are supported.
                  </td>
                </tr>

                <tr>
                  <td>
                    `bool`
                  </td>

                  <td>
                    True or false.
                  </td>
                </tr>

                <tr>
                  <td>
                    `DateTime`
                  </td>

                  <td>
                    A string representation following the ISO-8601 format, including time zone information:

                    Example: `2020-02-13T11:31:19.5767650-08:00`
                  </td>
                </tr>

                <tr>
                  <td>
                    `TimeSpan`
                  </td>

                  <td>
                    A decimal-based number representing number of seconds.
                  </td>
                </tr>

                <tr>
                  <td>
                    `arrays`, `Lists`, and other `IEnumerable` types
                  </td>

                  <td>
                    Serialized as a JSON array. Individual elements follow the same type conversion rules above. Null elements are filtered out. Empty arrays and arrays containing only null values are not recorded. Requires .NET agent version 10.50.0 or later.
                  </td>
                </tr>

                <tr>
                  <td>
                    everything else
                  </td>

                  <td>
                    The `ToString()` method will be applied. Custom types must have an implementation of `Object.ToString()` or they will throw an exception.
                  </td>
                </tr>
              </tbody>
            </table>
          </td>
        </tr>
      </tbody>
    </table>

    ### Returns

    A reference to the current span.

    ### Usage considerations

    For details about supported data types, see the [Custom Attributes guide](/docs/agents/net-agent/attributes/custom-attributes).

    ### Examples

    ```cs
    IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent();
    ISpan currentSpan = agent.CurrentSpan;

    currentSpan
        .AddCustomAttribute("customerName","Bob Smith")
        .AddCustomAttribute("currentAge",31)
        .AddCustomAttribute("birthday", new DateTime(2000, 02, 14))
        .AddCustomAttribute("waitTime", TimeSpan.FromMilliseconds(93842))
        .AddCustomAttribute("colors", new[] { "red", "green", "blue" })
        .AddCustomAttribute("ids", new List<int> { 1, 2, 3 });
    ```
  </Collapser>

  <Collapser
    id="SetName"
    title="SetName"
  >
    Changes the name of the current segment/span that will be reported to New Relic. For segments/spans resulting from custom instrumentation, the metric name reported to New Relic will be altered as well.

    This method requires .NET agent version and .NET agent API version 10.1.0 or higher.

    ### Syntax

    ```cs
    ISpan SetName(string name)
    ```

    ### Parameters

    <table>
      <thead>
        <tr>
          <th>
            Parameter
          </th>

          <th>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `name`

            _string_
          </td>

          <td>
            The new name for the span/segment.
          </td>
        </tr>
      </tbody>
    </table>

    ### Returns

    A reference to the current span.

    ### Examples

    ```cs
    [Trace]
    public void MyTracedMethod()
    {
        IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent(); 
        ISpan currentSpan = agent.CurrentSpan; 

        currentSpan.SetName("MyCustomName");
    }
    ```
  </Collapser>
</CollapserGroup>

````

**IgnoreApdex**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.IgnoreApdex()
```

Ignore the current transaction when calculating Apdex.

### Requirements

Compatible with all agent versions.

### Description

Ignores the current transaction when calculating your [Apdex score](/docs/apm/new-relic-apm/apdex/apdex-measuring-user-satisfaction). This is useful when you have either very short or very long transactions (such as file downloads) that can skew your Apdex score.

### Examples

```cs
NewRelic.Api.Agent.NewRelic.IgnoreApdex();
```

````

**IgnoreTransaction**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.IgnoreTransaction()
```

Do not instrument the current transaction.

### Requirements

* Compatible with all agent versions.
* Must be called inside a [transaction](/docs/accounts-partnerships/education/getting-started-new-relic/glossary#transaction).

### Description

Ignores the current transaction.

<Callout variant="tip">
  You can also ignore transactions [via a custom instrumentation XML file](/docs/agents/net-agent/custom-instrumentation/add-detail-transactions-xml-net#blocking-instrumentation).
</Callout>

### Examples

```cs
NewRelic.Api.Agent.NewRelic.IgnoreTransaction();
```

````

**IncrementCounter**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.IncrementCounter(string $metric_name)
```

Increment the counter for a custom metric by 1.

### Requirements

* Compatible with all agent versions.
* Compatible with all app types.

### Description

Increment the counter for a [custom metric](/docs/agents/manage-apm-agents/agent-metrics/custom-metrics) by 1. To view these custom metrics, use the [query builder](/docs/query-your-data/explore-query-data/query-builder/use-advanced-nrql-mode-specify-data) to search metrics and create customizable charts. See also [`RecordMetric()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#RecordMetric) and [`RecordResponseTimeMetric()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#RecordResponseTimeMetric).

<Callout variant="important">
  When creating a custom metric, start the name with `Custom/` (for example, `Custom/MyMetric`). For more on naming, see [Collect custom metrics](/docs/apm/agents/manage-apm-agents/agent-data/collect-custom-metrics/).
</Callout>

### Parameters

<table>
  <thead>
    <tr>
      <th width="25%">
        Parameter
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `$metric_name`

        _string_
      </td>

      <td>
        Required. The name of the metric to increment.
      </td>
    </tr>
  </tbody>
</table>

### Examples

```cs
NewRelic.Api.Agent.NewRelic.IncrementCounter("Custom/ExampleMetric");
```

````

**NoticeError**

### Overloads [#overloads]

Notice an error and report to New Relic, along with optional custom attributes.

````cs
NewRelic.Api.Agent.NewRelic.NoticeError(Exception $exception);
NewRelic.Api.Agent.NewRelic.NoticeError(Exception $exception, IDictionary<TKey, TValue> $attributes);
NewRelic.Api.Agent.NewRelic.NoticeError(string $error_message, IDictionary<TKey, TValue> $attributes);
NewRelic.Api.Agent.NewRelic.NoticeError(string $error_message, IDictionary<TKey, TValue> $attributes, bool $is_expected);
```

### Requirements

This API call is compatible with:

* All agent versions
* All app types

### Description

Notice an error and report it to New Relic along with optional custom attributes. For each transaction, the agent only retains the exception and attributes from the first call to `NoticeError()`. You can pass an actual exception, or pass a string to capture an arbitrary error message.

If this method is invoked within a [transaction](/docs/glossary/glossary/#transaction), the agent reports the exception within the parent transaction. If it is invoked outside of a transaction, the agent creates an [error trace](/docs/errors-inbox/apm-tab//#trace-details) and categorizes the error in the New Relic UI as a `NewRelic.Api.Agent.NoticeError` API call. If invoked outside of a transaction, the `NoticeError()` call will not contribute to the error rate of an application.

The agent adds the attributes only to the traced error; it does not send them to New Relic. For more information, see [`AddCustomAttribute()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#AddCustomAttribute).

When passing an exception to `NoticeError()`, determine the innermost exception using Microsoft's `Exception.GetBaseException()` API. This innermost exception represents the root cause of the error and is what is displayed in APM. The entire stack trace from the top-level exception is reported, as it provides relevant context and execution details. This approach offers the most specific error information from the base exception while preserving the complete context of how the error propagated through the application.

Errors reported with this API are still sent to New Relic when they are reported within a transaction that results in an HTTP status code, such as a `404`, that is configured to be ignored by agent configuration. For more information, see our documentation about [managing errors in APM](/docs/apm/agents/manage-apm-agents/agent-data/manage-errors-apm-collect-ignore-or-mark-expected).

Review the sections below to see examples of how to use this call.

<CollapserGroup>
  <Collapser
    id=""
    title="NoticeError(Exception)"
  >
    ```cs
    NewRelic.Api.Agent.NewRelic.NoticeError(Exception $exception)
    ```

    <table>
      <thead>
        <tr>
          <th width="25%">
            Parameter
          </th>

          <th>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `$exception`

            _Exception_
          </td>

          <td>
            Required. The `Exception` you want to instrument. Only the first 10,000 characters from the stack trace are retained.
          </td>
        </tr>
      </tbody>
    </table>
  </Collapser>

  <Collapser
    id=""
    title="NoticeError(Exception, IDictionary)"
  >
    ```cs
    NewRelic.Api.Agent.NewRelic.NoticeError(Exception $exception, IDictionary<TKey, TValue> $attributes)
    ```

    <table>
      <thead>
        <tr>
          <th width="25%">
            Parameter
          </th>

          <th>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `$exception`

            _Exception_
          </td>

          <td>
            Required. The `Exception` you want to instrument. Only the first 10,000 characters from the stack trace are retained.
          </td>
        </tr>

        <tr>
          <td>
            `$attributes`

            _IDictionary&lt;TKey, TValue>_
          </td>

          <td>
            Specify key/value pairs of attributes to annotate the error message. The `TKey` must be a string, the `TValue` can be a string or object.
          </td>
        </tr>
      </tbody>
    </table>
  </Collapser>

  <Collapser
    id="string-idictionary-overload"
    title="NoticeError(String, IDictionary)"
  >
    ```cs
    NewRelic.Api.Agent.NewRelic.NoticeError(string $error_message, IDictionary<TKey, TValue> $attributes)
    ```

    <table>
      <thead>
        <tr>
          <th width="25%">
            Parameter
          </th>

          <th>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `$error_message`

            _string_
          </td>

          <td>
            Required. Specify a string to report to New Relic as though it's an exception. This method creates both [error events and error traces](/docs/errors-inbox/apm-tab/#events).  Only the first 1023 characters are retained in error events, while error traces retain the full message.
          </td>
        </tr>

        <tr>
          <td>
            `$attributes`

            _IDictionary&lt;TKey, TValue>_
          </td>

          <td>
            Required (can be null). Specify key/value pairs of attributes to annotate the error message. The `TKey` must be a string, the `TValue` can be a string or object, to send no attributes, pass `null`.  

          </td>
        </tr>
      </tbody>
    </table>
  </Collapser>

  <Collapser
    id=""
    title="NoticeError(String, IDictionary, bool)"
  >
    ```cs
    NewRelic.Api.Agent.NewRelic.NoticeError(string $error_message, IDictionary<TKey, TValue> $attributes, bool $is_expected)
    ```

    <table>
      <thead>
        <tr>
          <th width="25%">
            Parameter
          </th>

          <th>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            `$error_message`

            _string_
          </td>

          <td>
            Required. Specify a string to report to New Relic as though it's an exception. This method creates both [error events and error traces](/docs/tutorial-error-tracking/respond-outages/).  Only the first 1023 characters are retained in error events, while error traces retain the full message.
          </td>
        </tr>

        <tr>
          <td>
            `$attributes`

            _IDictionary&lt;TKey, TValue>_
          </td>

          <td>
            Required (can be null). Specify key/value pairs of attributes to annotate the error message. The `TKey` must be a string, the `TValue` can be a string or object, to send no attributes, pass `null`.
          </td>
        </tr>

        <tr>
          <td>
            `$is_expected`

            _bool_
          </td>

          <td>
            Mark error as expected so that it won't affect Apdex score and error rate.
          </td>
        </tr>
      </tbody>
    </table>
  </Collapser>
</CollapserGroup>

### Examples

#### Pass an exception without custom attributes

```cs
try
{
    string ImNotABool = "43";
    bool.Parse(ImNotABool);
}
catch (Exception ex)
{
    NewRelic.Api.Agent.NewRelic.NoticeError(ex);
}
```

#### Pass an exception with custom attributes

```cs
try
{
    string ImNotABool = "43";
    bool.Parse(ImNotABool);
}
catch (Exception ex)
{
    var errorAttributes = new Dictionary<string, string>() {{"foo", "bar"},{"baz", "luhr"}};
    NewRelic.Api.Agent.NewRelic.NoticeError(ex, errorAttributes);
}
```

#### Pass an error message string with custom attributes

```cs
try
{
    string ImNotABool = "43";
    bool.Parse(ImNotABool);
}
catch (Exception ex)
{
    var errorAttributes = new Dictionary<string, string>{{"foo", "bar"},{"baz", "luhr"}};
    NewRelic.Api.Agent.NewRelic.NoticeError("String error message", errorAttributes);
}
```

#### Pass an error message string without custom attributes

```cs
try
{
    string ImNotABool = "43";
    bool.Parse(ImNotABool);
}
catch (Exception ex)
{
    NewRelic.Api.Agent.NewRelic.NoticeError("String error message", null);
}
```

#### Pass an error message string and mark it as expected

```cs
try
{
    string ImNotABool = "43";
    bool.Parse(ImNotABool);
}
catch (Exception ex)
{
    NewRelic.Api.Agent.NewRelic.NoticeError("String error message", null, true);
}
```

````

**RecordCustomEvent**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.RecordCustomEvent(string eventType, IEnumerable<string, object> attributeValues)
```

Records a custom event with the given name and attributes.

### Requirements

* Compatible with all agent versions.
* Compatible with all app types.

### Description

Records a [custom event](/docs/data-analysis/metrics/analyze-your-metrics/data-collection-metric-timeslice-event-data#event-data) with the given name and attributes, which you can query in the [query builder](/docs/query-your-data/explore-query-data/query-builder/introduction-query-builder). To verify if an event is being recorded correctly, look for the data in [dashboards](/docs/query-your-data/explore-query-data/dashboards/introduction-new-relic-one-dashboards).

<Callout variant="important">
  * Sending a lot of events can increase the memory overhead of the agent.
  * Additionally, posts greater than 1MB (10^6 bytes) in size will not be recorded regardless of the maximum number of events.
  * Custom events are limited to 64 attributes.
  * For more information about how custom attribute values are processed, see the [custom attributes](/docs/agents/net-agent/attributes/custom-attributes) guide.
</Callout>

### Parameters

<table>
  <thead>
    <tr>
      <th width="25%">
        Parameter
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `eventType`

        _string_
      </td>

      <td>
        Required. The name of the event type to record. Strings over 255 characters will result in the API call not being sent to New Relic. The name can only contain alphanumeric characters, underscores `_`, and colons `:`. For additional restrictions on event type names, see [Reserved words](/docs/data-apis/custom-data/custom-events/data-requirements-limits-custom-event-data/#reserved-words).
      </td>
    </tr>

    <tr>
      <td>
        `attributeValues`

        _IEnumerable&lt;string, object>_
      </td>

      <td>
        Required. Specify key/value pairs of attributes to annotate the event.
      </td>
    </tr>
  </tbody>
</table>

### Examples

#### Record values [#record-strings]

```cs
var eventAttributes = new Dictionary<string, object>() 
{
    {"foo", "bar"},
    {"alice", "bob"}, 
    {"age", 32}, 
    {"height", 21.3f}
};

NewRelic.Api.Agent.NewRelic.RecordCustomEvent("MyCustomEvent", eventAttributes);
```

````

**RecordMetric**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.RecordMetric(string $metric_name, single $metric_value)
```

Records a custom metric with the given name.

### Requirements

* Compatible with all agent versions.
* Compatible with all app types.

### Description

Records a [custom metric](/docs/agents/manage-apm-agents/agent-metrics/custom-metrics) with the given name. To view these custom metrics, use the [query builder](/docs/query-your-data/explore-query-data/query-builder/use-advanced-nrql-mode-specify-data) to search metrics and create customizable charts. See also [`IncrementCounter()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#IncrementCounter) and [`RecordResponseTimeMetric()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#RecordResponseTimeMetric).

<Callout variant="important">
  When creating a custom metric, start the name with `Custom/` (for example, `Custom/MyMetric`).
</Callout>

### Parameters

<table>
  <thead>
    <tr>
      <th width="25%">
        Parameter
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `$metric_name`

        _string_
      </td>

      <td>
        Required. The name of the metric to record. Only the first 255 characters are retained.
      </td>
    </tr>

    <tr>
      <td>
        `$metric_value`

        _single_
      </td>

      <td>
        Required. The quantity to record for the metric.
      </td>
    </tr>
  </tbody>
</table>

### Examples

#### Record response time of a sleeping process [#record-stopwatch]

```cs
Stopwatch stopWatch = Stopwatch.StartNew();
System.Threading.Thread.Sleep(5000);
stopWatch.Stop();
NewRelic.Api.Agent.NewRelic.RecordMetric("Custom/DEMO_Record_Metric", stopWatch.ElapsedMilliseconds);
```

````

**RecordResponseTimeMetric**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.RecordResponseTimeMetric(string $metric_name, Int64 $metric_value)
```

Records a custom metric with the given name and response time in milliseconds.

### Requirements

* Compatible with all agent versions.
* Compatible with all app types.

### Description

Records the response time in milliseconds for a [custom metric](/docs/agents/manage-apm-agents/agent-metrics/custom-metrics). To view these custom metrics, use the [query builder](/docs/query-your-data/explore-query-data/query-builder/use-advanced-nrql-mode-specify-data) to search metrics and create customizable charts. See also [`IncrementCounter()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#IncrementCounter) and [`RecordMetric()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#RecordMetric).

<Callout variant="important">
  When creating a custom metric, start the name with `Custom/` (for example, `Custom/MyMetric`).
</Callout>

### Parameters

<table>
  <thead>
    <tr>
      <th width="25%">
        Parameter
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `$metric_name`

        _string_
      </td>

      <td>
        Required. The name of the response time metric to record. Only the first 255 characters are retained.
      </td>
    </tr>

    <tr>
      <td>
        `$metric_value`

        _Int64_
      </td>

      <td>
        Required. The response time to record in milliseconds.
      </td>
    </tr>
  </tbody>
</table>

### Examples

#### Record response time of a sleeping process [#record-stopwatch]

```cs
Stopwatch stopWatch = Stopwatch.StartNew();
System.Threading.Thread.Sleep(5000);
stopWatch.Stop();
NewRelic.Api.Agent.NewRelic.RecordResponseTimeMetric("Custom/DEMO_Record_Response_Time_Metric", stopWatch.ElapsedMilliseconds);
```

````

**SetApplicationName**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.SetApplicationName(string $name[, string $name_2, string $name_3])
```

Set the app name for data rollup.

### Requirements

* Compatible with all agent versions.
* Compatible with all app types.

### Description

Set the application name(s) reported to New Relic. For more information about application naming, see [Name your .NET application](/docs/agents/net-agent/installation-configuration/name-your-net-application). This method is intended to be called once, during startup of an application.

<Callout variant="important">
  Updating the app name forces the agent to restart. The agent discards any unreported data associated with previous app names. Changing the app name multiple times during the lifecycle of an application is not recommended due to the associated data loss.
</Callout>

### Parameters

<table>
  <thead>
    <tr>
      <th width="25%">
        Parameter
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `$name`

        _string_
      </td>

      <td>
        Required. The primary application name.
      </td>
    </tr>

    <tr>
      <td>
        `$name_2`

        `$name_3`

        _string_
      </td>

      <td>
        Optional. Second and third names for app rollup. For more information, see [Use multiple names for an app](/docs/agents/manage-apm-agents/app-naming/use-multiple-names-app).
      </td>
    </tr>
  </tbody>
</table>

### Examples

```cs
NewRelic.Api.Agent.NewRelic.SetApplicationName("AppName1", "AppName2");
```

````

**SetErrorGroupCallback**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.SetErrorGroupCallback(Func<IReadOnlyDictionary<string,object>, string> errorGroupCallback);
```

Provide a callback method that takes an `IReadOnlyDictionary<string,object>` of attribute data, and returns an error group name.

### Requirements

This API call is compatible with:

* Agent version 10.9.0 or higher.
* All app types

### Description

Set a callback method that the agent will use to determine the error group name for error events and traces.  This name is used in the Errors Inbox to group errors into logical groups.

The callback method must accept a single argument of type `IReadOnlyDictionary<string,object>`, and return a string (the error group name). The `IReadOnlyDictionary` is a collection of [attribute data](/docs/apm/agents/manage-apm-agents/agent-data/agent-attributes/) associated with each error event, including custom attributes.

The exact list of attributes available for each error will vary depending on:

* What application code generated the error
* Agent configuration settings
* Whether any custom attributes were added

However, the following attributes should always exist:

* `error.class`
* `error.message`
* `stack_trace`
* `transactionName`
* `request.uri`
* `error.expected`

An empty string may be returned for the error group name when the error can't be assigned to a logical error group.

### Parameters

<table>
  <thead>
    <tr>
      <th width="25%">
        Parameter
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `$callback`

        _{'Func<IReadOnlyDictionary<string,object>,string>'}_
      </td>

      <td>
        The callback to determine the error group name based on attribute data.
      </td>
    </tr>
  </tbody>
</table>

### Examples

Group errors by error class name:

```cs
Func<IReadOnlyDictionary<string, object>, string> errorGroupCallback = (attributes) => {
    string errorGroupName = string.Empty;
    if (attributes.TryGetValue("error.class", out var errorClass))
    {
        if (errorClass.ToString() == "System.ArgumentOutOfRangeException" || errorClass.ToString() == "System.ArgumentNullException")
        {
            errorGroupName = "ArgumentErrors";
        }
        else
        {
            errorGroupName = "OtherErrors";
        }
    }
    return errorGroupName;
};

NewRelic.Api.Agent.NewRelic.SetErrorGroupCallback(errorGroupCallback);
```

Group errors by transaction name:

```cs
Func<IReadOnlyDictionary<string, object>, string> errorGroupCallback = (attributes) => {
    string errorGroupName = string.Empty;
    if (attributes.TryGetValue("transactionName", out var transactionName))
    {
    if (transactionName.ToString().IndexOf("WebTransaction/MVC/Home") != -1)
    {
    errorGroupName = "HomeControllerErrors";
    }
        else
        {
            errorGroupName = "OtherControllerErrors";
        }
    }
    return errorGroupName;
};

NewRelic.Api.Agent.NewRelic.SetErrorGroupCallback(errorGroupCallback);
```

````

**SetTransactionName**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.SetTransactionName(string $category, string $name)
```

Sets the name of the current transaction.

### Requirements

* Compatible with all agent versions.
* Must be called inside a [transaction](/docs/accounts-partnerships/education/getting-started-new-relic/glossary#transaction).

### Description

Set a custom transaction name, to be appended after an initial prefix (`WebTransaction` or `OtherTransaction`) based on the type of the current transaction. Before you use this call, ensure you understand the implications of [metric grouping issues](/docs/agents/manage-apm-agents/troubleshooting/metric-grouping-issues).

If you use this call multiple times within the same transaction, each call overwrites the previous call and the last call sets the name.

<Callout variant="important">
  Do not use brackets `[suffix]` at the end of your transaction name. New Relic automatically strips brackets from the name. Instead, use parentheses `(suffix)` or other symbols if needed.
</Callout>

Unique values like URLs, page titles, hex values, session IDs, and uniquely identifiable values should not be used in naming your transactions. Instead, add that data to the transaction as a custom parameter with the [`AddCustomAttribute()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#AddCustomAttribute) call.

<Callout variant="important">
  Do not create more than 1000 unique transaction names (for example, avoid naming by URL if possible). This will make your charts less useful, and you may run into limits New Relic sets on the number of unique transaction names per account. It also can slow down the performance of your application.
</Callout>

### Parameters

<table>
  <thead>
    <tr>
      <th width="25%">
        Parameter
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `$category`

        _string_
      </td>

      <td>
        Required. The category of this transaction, which you can use to distinguish different types of transactions. Defaults to <DNT>**`Custom`**</DNT>. Only the first 255 characters are retained.
      </td>
    </tr>

    <tr>
      <td>
        `$name`

        _string_
      </td>

      <td>
        Required. The name of the transaction. Only the first 255 characters are retained.
      </td>
    </tr>
  </tbody>
</table>

### Examples

This example shows use of this API in an ASP.NET Core MVC controller. A transaction is created automatically by the agent's instrumentation for ASP.NET Core. The first part of the transaction name will continue to be `WebTransaction`.

```cs
public class HomeController : Controller
{

  public IActionResult Order(string product)
  { 

    // The commented-out API call below is probably a bad idea and will lead to a metric grouping issue (MGI)
    // because too many transaction names will be created. Don't do this.
    //NewRelic.Api.Agent.NewRelic.SetTransactionName("Other", $"ProductOrder-{product}");

    // Do this instead if you want to record request-specific data about this MVC endpoint
    var tx = NewRelic.Api.Agent.NewRelic.GetAgent().CurrentTransaction;
    tx.AddCustomAttribute("productName", product);

    // The default transaction name at this point will be: WebTransaction/MVC/Home/Order

    // Set custom transaction name
    NewRelic.Api.Agent.NewRelic.SetTransactionName("Other", "OrderProduct");

    // Transaction name is now: WebTransaction/Other/OrderProduct

    return View();
  }
}  
```

This example shows use of this API in a console application. Note the `[Transaction]` custom instrumentation attribute, which is necessary to create a transaction for the example method.  The first part of the transaction name will continue to be `OtherTransaction`.

```cs
using NewRelic.Api.Agent;

namespace SetApplicationNameConsoleExample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Hello, World!");

        var start = DateTime.Now;
        while (DateTime.Now - start < TimeSpan.FromMinutes(2))
        {
            DoSomething();
            Thread.Sleep(TimeSpan.FromSeconds(5));
        }
    }

    [Transaction]  // Attribute-based custom instrumentation to create a transaction for this method
    static void DoSomething()
    {
        Console.WriteLine("Doing something: " + Guid.NewGuid().ToString());

        // Transaction name from default naming at this point is: OtherTransaction/Custom/SetApplicationNameConsoleExample.Program/DoSomething

        NewRelic.Api.Agent.NewRelic.SetTransactionName("Console", "MyCustomTransactionName");

        // Transaction name at this point is: OtherTransaction/Console/MyCustomTransactionName

        // Note, however, that this transaction will still have a child segment (span) named "SetApplicationNameConsoleExample.Program.DoSomething"
    }
  }
}
```

````

**SetTransactionUri**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.SetTransactionUri(Uri $uri)
```

Sets the URI of the current transaction.

### Requirements

* Must be called inside a [transaction](/docs/accounts-partnerships/education/getting-started-new-relic/glossary#transaction).
* Agent version 6.16 or higher.

<Callout variant="important">
  This method only works when used within a transaction created using the `Transaction` attribute with the `Web` property set to `true`. (See [Custom instrumentation via attributes](/docs/agents/net-agent/api-guides/net-agent-api-instrument-using-attributes).) It provides support for custom web-based frameworks that the agent does not automatically support.
</Callout>

### Description

Set the URI of the current transaction. The URI appears in the `request.uri` attribute of [transaction traces](/docs/apm/transactions/transaction-traces/transaction-traces) and [transaction events](/docs/using-new-relic/metrics/analyze-your-metrics/data-collection-metric-timeslice-event-data), and it also can affect transaction naming.

If you use this call multiple times within the same transaction, each call overwrites the previous call. The last call sets the URI.

**Note**: as of agent version 8.18, the `request.uri` attribute's value is set to the value of the `Uri.AbsolutePath` property of the `System.Uri` object passed to the API.

### Parameters

<table>
  <thead>
    <tr>
      <th width="25%">
        Parameter
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `$uri`

        _Uri_
      </td>

      <td>
        The URI of this transaction.
      </td>
    </tr>
  </tbody>
</table>

### Examples

```cs
var uri = new System.Uri("https://www.mydomain.com/path");
NewRelic.Api.Agent.NewRelic.SetTransactionUri(uri);
```

````

**SetUserParameters**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.SetUserParameters(string $user_value, string $account_value, string $product_value)
```

Create user-related custom attributes. [`AddCustomAttribute`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#AddCustomAttribute) is more flexible.

### Requirements

* Compatible with all agent versions.
* Must be called inside a [transaction](/docs/accounts-partnerships/education/getting-started-new-relic/glossary#transaction).

### Description

<Callout variant="tip">
  This call only allows you to assign values to pre-existing keys. For a more flexible method to create key/value pairs, use [`AddCustomAttribute()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#AddCustomAttribute).
</Callout>

Define user-related [custom attributes](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#AddCustomAttribute)to associate with a browser page view (user name, account name, and product name). The values are automatically associated with pre-existing keys (`user`, `account`, and `product`), then attached to the parent APM transaction. You can also [attach (or "forward") these attributes](/docs/insights/new-relic-insights/decorating-events/insights-custom-attributes#forwarding-attributes) to browser [PageView](/docs/agents/manage-apm-agents/agent-metrics/agent-attributes#destinations) events.

### Parameters

<table>
  <thead>
    <tr>
      <th width="25%">
        Parameter
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `$user_value`

        _string_
      </td>

      <td>
        Required (can be null). Specify a name or username to associate with this page view. This value is assigned to the `user` key.
      </td>
    </tr>

    <tr>
      <td>
        `$account_value`

        _string_
      </td>

      <td>
        Required (can be null). Specify the name of a user account to associate with this page view. This value is assigned to the `account` key.
      </td>
    </tr>

    <tr>
      <td>
        `$product_value`

        _string_
      </td>

      <td>
        Required (can be null). Specify the name of a product to associate with this page view. This value is assigned to the `product` key.
      </td>
    </tr>
  </tbody>
</table>

### Examples

#### Record three user attributes

```cs
NewRelic.Api.Agent.NewRelic.SetUserParameters("MyUserName", "MyAccountName", "MyProductName");
```

#### Record two user attributes and one empty attribute

```cs
NewRelic.Api.Agent.NewRelic.SetUserParameters("MyUserName", "", "MyProductName");
```

````

**StartAgent**

### Syntax

````cs
NewRelic.Api.Agent.NewRelic.StartAgent()
```

Start the agent if it hasn't already started. Usually unnecessary.

### Requirements

* Compatible with all agent versions.
* Compatible with all app types.

### Description

Starts the agent if it hasn't already been started. This call is usually unnecessary, since the agent starts automatically when it hits an instrumented method unless you disable [`autoStart`](/docs/apm/agents/net-agent/configuration/net-agent-configuration/#service-autoStart). If you use [`SetApplicationName()`](/docs/apm/agents/net-agent/net-agent-api/net-agent-api/#SetApplicationName), ensure you set the app name **before** you start the agent.

<Callout variant="tip">
  This method starts the agent asynchronously (meaning it won't block app startup) unless you enable [`syncStartup`](/docs/apm/agents/net-agent/configuration/net-agent-configuration/#service-syncStartup) or [`sendDataOnExit`](/docs/apm/agents/net-agent/configuration/net-agent-configuration/#service-sendDataOnExit).
</Callout>

### Examples

```cs
NewRelic.Api.Agent.NewRelic.StartAgent();
```

````

**TraceMetadata**

### Syntax

````cs
NewRelic.Api.Agent.TraceMetadata;
```

Returns properties in the current execution environment used to support tracing.

### Requirements

* Agent version 8.19 or higher.
* Compatible with all app types.
* [Distributed tracing must be enabled](/docs/agents/net-agent/configuration/net-agent-configuration#distributed_tracing) to get meaningful values.

### Description

Provides access to the following properties:

### Properties

<table>
  <thead>
    <tr>
      <th width="25%">
        Name
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `TraceId`
      </td>

      <td>
        Returns a string representing the currently executing trace. If the trace ID is not available, or distributed tracing is disabled, the value will be `string.Empty`.
      </td>
    </tr>

    <tr>
      <td>
        `SpanId`
      </td>

      <td>
        Returns a string representing the currently executing span. If the span ID is not available, or distributed tracing is disabled, the value will be `string.Empty`.
      </td>
    </tr>

    <tr>
      <td>
        `IsSampled`
      </td>

      <td>
        Returns `true` if the current trace is sampled for inclusion, `false` if it is sampled out.
      </td>
    </tr>
  </tbody>
</table>

### Examples

```cs
IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent();
ITraceMetadata traceMetadata = agent.TraceMetadata;
string traceId = traceMetadata.TraceId;
string spanId = traceMetadata.SpanId;
bool isSampled = traceMetadata.IsSampled;
```

````
