# WebhookSubscription

> Tracon documentation. Tracon is a .NET package family that adds a control
> plane on Microsoft Agent Framework, published as NuGet packages that run
> inside your own ASP.NET Core application.
>
> Page: https://tracon.dev/api/tracon.webhooksubscription/
> Summary: WebhookSubscription: An external system's event subscription.

<div class="api-provenance">Namespace Tracon · Assembly <code>Tracon.Abstractions.dll</code></div>

An external system's event subscription.

```csharp
public sealed record WebhookSubscription : IEquatable<WebhookSubscription>
```

<dl class="api-relations"><dt>Inheritance</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object">object</a> ← <a href="/api/tracon.webhooksubscription/">WebhookSubscription</a></dd><dt>Implements</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.iequatable-1">IEquatable&lt;WebhookSubscription&gt;</a></dd><dt>Inherited Members</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object.gettype">object.GetType()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.tostring">object.ToString()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)">object.Equals(object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)">object.Equals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.referenceequals">object.ReferenceEquals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.gethashcode">object.GetHashCode()</a></dd></dl>

## Remarks

This record **has no secret field**. The signing secret
does not sit in the database; only the name of the configuration key the
value is read from ([WebhookSubscription.SecretConfigurationKey](/api/tracon.webhooksubscription/#Tracon_WebhookSubscription_SecretConfigurationKey)) sits here, and
the value is resolved at run time through `IConfiguration`.

## Constructors

### <a id="Tracon_WebhookSubscription__ctor"></a> WebhookSubscription\(\)

```csharp
public WebhookSubscription()
```

## Properties

### <a id="Tracon_WebhookSubscription_ConsecutiveFailures"></a> ConsecutiveFailures

The consecutive-failure count. Once the threshold is exceeded, the
subscription disables itself and is written to the audit trail.

```csharp
public int ConsecutiveFailures { get; init; }
```

#### Property Value

 [int](https://learn.microsoft.com/dotnet/api/system.int32)

### <a id="Tracon_WebhookSubscription_CreatedAt"></a> CreatedAt

The creation time (UTC).

```csharp
public required DateTimeOffset CreatedAt { get; init; }
```

#### Property Value

 [DateTimeOffset](https://learn.microsoft.com/dotnet/api/system.datetimeoffset)

### <a id="Tracon_WebhookSubscription_Enabled"></a> Enabled

Whether the subscription is enabled.

```csharp
public bool Enabled { get; init; }
```

#### Property Value

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_WebhookSubscription_Events"></a> Events

The subscribed event names. See [WebhookEvents](/api/tracon.webhookevents/).

```csharp
public required IReadOnlyList<string> Events { get; init; }
```

#### Property Value

 [IReadOnlyList](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlylist\-1)<[string](https://learn.microsoft.com/dotnet/api/system.string)\>

### <a id="Tracon_WebhookSubscription_HeaderConfigurationKeys"></a> HeaderConfigurationKeys

Credential headers, as a map from the header name to the NAME of the
configuration key its value is read from. The value is resolved through
`IConfiguration` on every delivery and is never stored.

```csharp
public IReadOnlyDictionary<string, string> HeaderConfigurationKeys { get; init; }
```

#### Property Value

 [IReadOnlyDictionary](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlydictionary\-2)<[string](https://learn.microsoft.com/dotnet/api/system.string), [string](https://learn.microsoft.com/dotnet/api/system.string)\>

#### Examples

```csharp
var record = new WebhookSubscription
{
    Id = Guid.NewGuid(),
    TenantId = "acme",
    Name = "orders",
    Url = "https://orders.example.com/hook",
    Events = [WebhookEvents.RunCompleted],
    CreatedAt = DateTimeOffset.UtcNow,
    UpdatedAt = DateTimeOffset.UtcNow,
    HeaderConfigurationKeys = new Dictionary<string, string>
    {
        ["X-Api-Key"] = "Tracon:WebhookSecrets:acme:OrdersKey",
    },
};
```

#### Remarks

Every key name must sit under
`TraconWebhookOptions.AllowedConfigurationPrefix`, inside the
tenant's own key space (`{prefix}{tenantId}:...`; a flat name
directly under the prefix belongs to the default tenant). The rule is
checked on save and again before every delivery; a delivery whose
subscription names a key outside the tenant is dropped.

A header name may appear only once across [WebhookSubscription.Headers](/api/tracon.webhooksubscription/#Tracon_WebhookSubscription_Headers) and
this map, compared case-insensitively, and may not be one of the
headers Tracon sets itself (`X-Tracon-*`). The map counts toward
`TraconWebhookOptions.MaxExtraHeaders` together with
[WebhookSubscription.Headers](/api/tracon.webhooksubscription/#Tracon_WebhookSubscription_Headers).

### <a id="Tracon_WebhookSubscription_Headers"></a> Headers

Extra headers added to every request. An HTTP response never returns a
stored value: it carries every header name with the value `***`.

```csharp
public IReadOnlyDictionary<string, string> Headers { get; init; }
```

#### Property Value

 [IReadOnlyDictionary](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlydictionary\-2)<[string](https://learn.microsoft.com/dotnet/api/system.string), [string](https://learn.microsoft.com/dotnet/api/system.string)\>

#### Remarks

An authentication header is **not written here**: the
value would be stored in the database. Declare it in
`HeaderConfigurationKeys` instead, and use
[WebhookSubscription.SecretConfigurationKey](/api/tracon.webhooksubscription/#Tracon_WebhookSubscription_SecretConfigurationKey) for signing. The HTTP save rejects a
header whose name looks like a credential (`Authorization`,
`X-Api-Key`, `Cookie`, any name ending in `-key`).

The read, list and save responses mask every value. A save whose
header value is `***` is rejected, so a client that reads, edits
and saves a subscription must send every header value again.

### <a id="Tracon_WebhookSubscription_Id"></a> Id

The subscription identifier.

```csharp
public required Guid Id { get; init; }
```

#### Property Value

 [Guid](https://learn.microsoft.com/dotnet/api/system.guid)

### <a id="Tracon_WebhookSubscription_Name"></a> Name

The name, unique within the tenant.

```csharp
public required string Name { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

### <a id="Tracon_WebhookSubscription_SecretConfigurationKey"></a> SecretConfigurationKey

The **name** of the configuration key the signing secret
is read from. Not the secret itself.

```csharp
public string? SecretConfigurationKey { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

#### Remarks

Example: `"Tracon:WebhookSecrets:order-service"`. The value
lives in `dotnet user-secrets` or an environment variable. If
empty, requests are not signed.

### <a id="Tracon_WebhookSubscription_TenantId"></a> TenantId

The tenant the subscription belongs to.

```csharp
public required string TenantId { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

### <a id="Tracon_WebhookSubscription_UpdatedAt"></a> UpdatedAt

The last-updated time (UTC).

```csharp
public required DateTimeOffset UpdatedAt { get; init; }
```

#### Property Value

 [DateTimeOffset](https://learn.microsoft.com/dotnet/api/system.datetimeoffset)

### <a id="Tracon_WebhookSubscription_Url"></a> Url

The address events are sent to.

```csharp
public required string Url { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

#### Remarks

The address goes through an SSRF check: only `https` (or
`http` for loopback), private network ranges are rejected,
redirects are not followed.

## Methods

### <a id="Tracon_WebhookSubscription_Equals_System_Object_"></a> Equals\(object?\)

```csharp
public override bool Equals(object? obj)
```

#### Parameters

`obj` [object](https://learn.microsoft.com/dotnet/api/system.object)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_WebhookSubscription_Equals_Tracon_WebhookSubscription_"></a> Equals\(WebhookSubscription?\)

```csharp
public bool Equals(WebhookSubscription? other)
```

#### Parameters

`other` [WebhookSubscription](/api/tracon.webhooksubscription/)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_WebhookSubscription_GetHashCode"></a> GetHashCode\(\)

```csharp
public override int GetHashCode()
```

#### Returns

 [int](https://learn.microsoft.com/dotnet/api/system.int32)

### <a id="Tracon_WebhookSubscription_ToString"></a> ToString\(\)

```csharp
public override string ToString()
```

#### Returns

 [string](https://learn.microsoft.com/dotnet/api/system.string)

## Operators

### <a id="Tracon_WebhookSubscription_op_Equality_Tracon_WebhookSubscription_Tracon_WebhookSubscription_"></a> operator ==\(WebhookSubscription?, WebhookSubscription?\)

```csharp
public static bool operator ==(WebhookSubscription? left, WebhookSubscription? right)
```

#### Parameters

`left` [WebhookSubscription](/api/tracon.webhooksubscription/)?

`right` [WebhookSubscription](/api/tracon.webhooksubscription/)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_WebhookSubscription_op_Inequality_Tracon_WebhookSubscription_Tracon_WebhookSubscription_"></a> operator \!=\(WebhookSubscription?, WebhookSubscription?\)

```csharp
public static bool operator !=(WebhookSubscription? left, WebhookSubscription? right)
```

#### Parameters

`left` [WebhookSubscription](/api/tracon.webhooksubscription/)?

`right` [WebhookSubscription](/api/tracon.webhooksubscription/)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)
