> ## Documentation Index
> Fetch the complete documentation index at: https://eurusys-6c0957fa.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# C# (.NET)

> Integrate the MBKYC SDK into a .NET application on Windows or Linux.

The C# SDK gives .NET apps Emirates ID reading and fingerprint capture, distributed as the `MBKYC.Sdk` NuGet package. All async operations return `Task<T>` and honour `CancellationToken`.

<Card title="Download the example" icon="download" href="/examples/mbkyc-csharp-example.zip" cta="mbkyc-csharp-example.zip">
  A self-contained CLI. Populate `deps/` (see below), fill in the config block, and `dotnet run`.
</Card>

<Accordion title="Populating the example's deps/ folder from the package" icon="box-archive">
  The downloadable example references the SDK from local files — a `<Reference HintPath="deps/MBKYC.dll">` plus `deps/runtimes/` in its `.csproj` — so it builds without configuring a NuGet source. The `MBKYC.Sdk` package is self-contained (managed DLL **and** native runtimes), and a `.nupkg` is just a ZIP archive, so you extract those two things from it:

  ```sh theme={null}
  # 1. Download the package (.nupkg) — it's a zip. The path below is the NuGet v3
  #    "flat container" URL on the Nexus repository (repo.client.ae is your
  #    ICP-proxied host placeholder); adjust host and version as needed.
  curl -u "$NEXUS_USER:$NEXUS_PASSWORD" -L \
    -o MBKYC.Sdk.nupkg \
    "https://repo.client.ae/repository/mbkyc-nuget/v3/content/mbkyc.sdk/0.5.0/mbkyc.sdk.0.5.0.nupkg"

  # 2. Unzip (rename to .zip first if your tool insists on the extension).
  unzip MBKYC.Sdk.nupkg -d MBKYC.Sdk

  # 3. Copy the managed DLL and the native runtimes into the example's deps/.
  cp    MBKYC.Sdk/lib/net6.0/MBKYC.dll  deps/MBKYC.dll   # managed assembly
  cp -R MBKYC.Sdk/runtimes              deps/runtimes    # osx-arm64 / osx-x64 / linux-x64 / win-x64
  ```

  The package ships native libraries for all four runtime IDs; the example's `.csproj` copies the one matching your platform next to the build output automatically. For a real project, prefer the `<PackageReference>` below over vendoring these files.
</Accordion>

## Install

Configure the Nexus NuGet source ([Configure Nexus](/distribution/configure-nexus#nuget-net)), then:

```xml theme={null}
<PackageReference Include="MBKYC.Sdk" Version="0.5.0" />
```

The package runs on Windows, Linux, and macOS out of the box. Card-read and fingerprint flows require the matching hardware support installed on the machine — see [Supported devices](/distribution/supported-devices).

## Initialize

```csharp theme={null}
using MBKYC;

using var mbkyc = MBKYC.Create(
    baseUrl:       "https://api.client.ae",
    apiKeyId:      "key-id",
    tokenSigner:   myTokenSigner,   // ITokenSigner — signs JWT inputs via your backend
    logConfig:     new LogConfig(new DirectoryInfo("/var/log/myapp")),
    httpTimeoutMs: 30000,
    extraHeaders:  new Dictionary<string, string> { ["X-Custom-Header"] = "..." } // optional
);
```

The API secret never enters the SDK. You pass an `ITokenSigner` whose `SignAsync(byte[] signingInput, CancellationToken)` routes the input to the holder of the API secret (your backend), signs it, and returns the signature. See [Authentication](/concepts/authentication).

## Register & validate

```csharp theme={null}
var readers = await mbkyc.ListSmartcardReadersAsync(ct);
await mbkyc.RegisterDeviceAsync("lobby-kiosk");
```

<Info>
  To read a card or capture a fingerprint, install the matching [desktop service](/distribution/services-overview) first — `mbkyc-pcsc-service` for card readers and your fingerprint vendor's service. Without them, the reader lists return empty. Manual entry needs no services.
</Info>

The request type you pass to `ValidateAsync` determines which document is validated and what hardware it needs.

<Tabs>
  <Tab title="Emirates ID">
    **Manual entry** — no hardware required.

    ```csharp theme={null}
    var result = await mbkyc.ValidateAsync(new EmiratesIdManualRequest {
        IdNumber       = "784-XXXX-XXXXXXX-X",
        DocumentNumber = "...",
        Nationality    = "ARE",
        // optional: DateOfBirth, IssueDate, ExpiryDate, Fingerprint, ClientReferenceId
    });
    ```

    **Card read** — needs a smart card reader + the PC/SC desktop service.

    ```csharp theme={null}
    var result = await mbkyc.ValidateAsync(new EmiratesIdCardRequest {
        ReaderId = readers[0].Id,
        // optional: CardDipTimeoutMs, Fingerprint, ClientReferenceId
    });
    ```

    **+ Fingerprint** — pass the `Fingerprint` argument to either request above (needs a fingerprint sensor + its service).

    ```csharp theme={null}
    var result = await mbkyc.ValidateAsync(new EmiratesIdCardRequest {
        ReaderId    = readers[0].Id,
        Fingerprint = new FingerprintConfig(fpReaderId, recommendationHandler, captureTimeoutMs: 10000),
    });
    ```
  </Tab>

  <Tab title="Passport">
    **Manual entry** — no hardware required. No biometric variant.

    ```csharp theme={null}
    var result = await mbkyc.ValidateAsync(new PassportManualRequest {
        PassportNumber = "...",
        PassportType   = "...",
        Nationality    = "ARE",
        // optional: DateOfBirth, IssueDate, ExpiryDate, ClientReferenceId
    });
    ```
  </Tab>
</Tabs>

## Biometrics

Set the `Fingerprint` property (`ReaderId`, `RecommendationHandler`, `CaptureTimeoutMs`). The recommendation handler is a delegate the SDK invokes mid-flow with the Validation Gateway's ranked finger candidates. See [Biometrics](/concepts/biometrics).

## Cancellation & errors

`CancellationToken` cancels an in-flight operation; the task then resolves with a `TaskCanceledException`. Failures surface as `MBKYCException`:

```csharp theme={null}
try
{
    await mbkyc.ValidateAsync(request);
}
catch (MBKYCException ex)
{
    Console.WriteLine($"code={(int)ex.ErrorCode} msg={ex.Message}");
}
```

`ErrorCode` is a strongly-typed enum; see the [error reference](/reference/error-codes).

<Info>
  `MBKYC` implements `IDisposable` — always `using` it (or `Dispose`) to release resources and flush logs.
</Info>

## Full API reference

All async methods return `Task<T>` and accept an optional `CancellationToken`. Shared types are in [Data types](/reference/data-types).

| Method                                                                                                | Returns                           |
| ----------------------------------------------------------------------------------------------------- | --------------------------------- |
| `MBKYC.Create(baseUrl, apiKeyId, tokenSigner, logConfig, httpTimeoutMs = 30000, extraHeaders = null)` | `MBKYC`                           |
| `ListSmartcardReadersAsync(ct)`                                                                       | `Task<IReadOnlyList<ReaderInfo>>` |
| `ListFingerprintReadersAsync(ct)`                                                                     | `Task<IReadOnlyList<ReaderInfo>>` |
| `RegisterDeviceAsync(name, ct)`                                                                       | `Task`                            |
| `CheckRegistrationAsync(ct)`                                                                          | `Task<RegistrationStatus>`        |
| `ValidateAsync(request, ct)`                                                                          | `Task<VerificationResult>`        |
| `ExportLogsAsync(path, ct)`                                                                           | `Task`                            |
| `Dispose()`                                                                                           | — (`IDisposable`)                 |

**Validation request types:**

```csharp theme={null}
new EmiratesIdCardRequest   { ReaderId, CardDipTimeoutMs?, Fingerprint?, ClientReferenceId? }
new EmiratesIdManualRequest { IdNumber, DocumentNumber, Nationality,
                              DateOfBirth?, IssueDate?, ExpiryDate?, Fingerprint?, ClientReferenceId? }
new PassportManualRequest   { PassportNumber, PassportType, Nationality,
                              DateOfBirth?, IssueDate?, ExpiryDate?, ClientReferenceId? }

new FingerprintConfig(fpReaderId, recommendationHandler, captureTimeoutMs: 10000)
```

**Export logs:**

```csharp theme={null}
await mbkyc.ExportLogsAsync("/tmp/mbkyc-logs.tar.zst");
```

Errors throw [`MBKYCException`](/reference/error-codes) with a typed `ErrorCode`.
