RoodFluweel.Publiq.EntryApi 0.2.2

dotnet add package RoodFluweel.Publiq.EntryApi --version 0.2.2
                    
NuGet\Install-Package RoodFluweel.Publiq.EntryApi -Version 0.2.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RoodFluweel.Publiq.EntryApi" Version="0.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RoodFluweel.Publiq.EntryApi" Version="0.2.2" />
                    
Directory.Packages.props
<PackageReference Include="RoodFluweel.Publiq.EntryApi" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RoodFluweel.Publiq.EntryApi --version 0.2.2
                    
#r "nuget: RoodFluweel.Publiq.EntryApi, 0.2.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RoodFluweel.Publiq.EntryApi@0.2.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RoodFluweel.Publiq.EntryApi&version=0.2.2
                    
Install as a Cake Addin
#tool nuget:?package=RoodFluweel.Publiq.EntryApi&version=0.2.2
                    
Install as a Cake Tool

RoodFluweel.Publiq.EntryClient

.NET SDK for interacting with the Publiq UiTdatabank APIs, including Entry, Taxonomy, Search, and UiTPAS APIs.

Project Structure

This solution is organized as follows:

RoodFluweel.Publiq.EntryClient/
├── src/
│   ├── RoodFluweel.Publiq.Common/        # Shared auth providers & endpoints
│   ├── RoodFluweel.Publiq.EntryApi/      # Entry API client
│   ├── RoodFluweel.Publiq.TaxonomyApi/   # Taxonomy API client
│   ├── RoodFluweel.Publiq.SearchApi/     # Search API client
│   └── RoodFluweel.Publiq.UitpasApi/     # UiTPAS API client
├── samples/
│   └── RoodFluweel.Publiq.Demo/          # Console demo application
├── tests/
│   ├── RoodFluweel.Publiq.Common.Tests/
│   ├── RoodFluweel.Publiq.EntryApi.Tests/
│   ├── RoodFluweel.Publiq.TaxonomyApi.Tests/
│   ├── RoodFluweel.Publiq.SearchApi.Tests/
│   └── RoodFluweel.Publiq.UitpasApi.Tests/
└── .github/workflows/                    # GitHub Actions (build, test & NuGet publish)

Getting Started

Installation

Install the client you need from NuGet (each API client pulls in RoodFluweel.Publiq.Common automatically):

dotnet add package RoodFluweel.Publiq.EntryApi      # UiTdatabank Entry API
dotnet add package RoodFluweel.Publiq.SearchApi     # UiTdatabank Search API
dotnet add package RoodFluweel.Publiq.TaxonomyApi   # UiTdatabank Taxonomy API
dotnet add package RoodFluweel.Publiq.UitpasApi     # UiTPAS API

Or add a project reference when working inside this repository:

dotnet add reference path/to/src/RoodFluweel.Publiq.EntryApi/RoodFluweel.Publiq.EntryApi.csproj

Environments

publiq exposes a test and a production environment. Credentials are environment specific: you initially receive credentials that only work on the test environment, and receive production credentials after publiq validates your integration. See environments.

All factory methods accept a PubliqEnvironment parameter, which selects both the API base URL and the matching authorization server:

API Test Production
Entry https://io-test.uitdatabank.be https://io.uitdatabank.be
Search https://search-test.uitdatabank.be https://search.uitdatabank.be
Taxonomy https://taxonomy.uitdatabank.be (same; production only)
UiTPAS https://api-test.uitpas.be https://api.uitpas.be
UiTiD (tokens) https://account-test.uitid.be https://account.uitid.be

The default is PubliqEnvironment.Test.

Authentication

Each publiq API supports specific authentication methods:

API Client identification Client access tokens
Search API ✅ ✅
Entry API ❌ ✅
UiTPAS API ❌ ✅
Taxonomy API no authentication needed

Client identification (Search API)

The Search API only requires your client id, sent as an x-client-id header:

using RoodFluweel.Publiq.SearchApi;
using RoodFluweel.Publiq.Common;

var searchClient = SearchClientFactory.CreateWithClientIdentification(
    "your-client-id", PubliqEnvironment.Test);

var events = await searchClient.Events.GetAsync();

Client access tokens (Entry API, UiTPAS API)

For backend systems, use the OAuth2 client credentials flow. Tokens are requested from publiq's UiTiD authorization server and cached automatically until shortly before they expire:

using RoodFluweel.Publiq.EntryApi;
using RoodFluweel.Publiq.Common;

var entryClient = EntryClientFactory.CreateWithClientCredentials(
    clientId: "your-client-id",
    clientSecret: "your-client-secret",
    environment: PubliqEnvironment.Test);

⚠️ Client access tokens must only be used from backend systems. Browsers and native applications cannot securely store the client secret.

Dynamic credentials (multi-tenant)

For multi-tenant applications where credentials need to be resolved at runtime:

using RoodFluweel.Publiq.Common;

// Implement ICredentialsProvider to resolve credentials dynamically
public class TenantCredentialsProvider : ICredentialsProvider
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly ITenantService _tenantService;

    public TenantCredentialsProvider(IHttpContextAccessor httpContextAccessor, ITenantService tenantService)
    {
        _httpContextAccessor = httpContextAccessor;
        _tenantService = tenantService;
    }

    public async Task<(string ClientId, string ClientSecret)> GetCredentialsAsync(CancellationToken cancellationToken = default)
    {
        // Resolve tenant from HTTP context (e.g., from route, header, or claim)
        var tenantId = _httpContextAccessor.HttpContext?.GetTenantId();

        // Fetch credentials from database, configuration service, or key vault
        var credentials = await _tenantService.GetCredentialsAsync(tenantId, cancellationToken);

        return (credentials.ClientId, credentials.ClientSecret);
    }
}

// Register in DI container
services.AddScoped<ICredentialsProvider, TenantCredentialsProvider>();

// Create client with credentials provider
var credentialsProvider = serviceProvider.GetRequiredService<ICredentialsProvider>();
var entryClient = EntryClientFactory.CreateWithClientCredentials(credentialsProvider, PubliqEnvironment.Test);

Tokens are cached per client id, so different tenants get separate cached tokens and the token endpoint is not hit for every API request.

Requesting credentials

You can request free test credentials in publiq platform, publiq's self-service portal. See requesting credentials.

Usage

Entry API (read & write)

using RoodFluweel.Publiq.EntryApi;
using RoodFluweel.Publiq.Common;

var entryClient = EntryClientFactory.CreateWithClientCredentials("client-id", "client-secret");

// Read an event
var ev = await entryClient.Events[eventId].GetAsync();

// Create an event
var response = await entryClient.Events.PostAsync(eventPostBody);

// Read a place
var place = await entryClient.Places[placeId].GetAsync();

Search API

using RoodFluweel.Publiq.SearchApi;

var searchClient = SearchClientFactory.CreateWithClientIdentification("client-id");
var results = await searchClient.Events.GetAsync(config =>
{
    config.QueryParameters.Q = "regions:nis-24062";
});
Console.WriteLine($"Found {results.TotalItems} events");

Taxonomy API

using RoodFluweel.Publiq.TaxonomyApi;

// No authentication needed
var taxonomyClient = TaxonomyClientFactory.CreateAnonymous();
var terms = await taxonomyClient.Terms.GetAsync();

UiTPAS API

using RoodFluweel.Publiq.UitpasApi;
using RoodFluweel.Publiq.Common;

var uitpasClient = UitpasClientFactory.CreateWithClientCredentials("client-id", "client-secret");
// Use UiTPAS client methods

Demo application

The samples/RoodFluweel.Publiq.Demo console application demonstrates the clients against the live publiq test environment:

cd samples/RoodFluweel.Publiq.Demo

# Works without credentials: fetches taxonomy terms anonymously
dotnet run

# Configure credentials to also run the Search & Entry API demos
dotnet user-secrets set "Publiq:ClientId" "your-client-id"
dotnet user-secrets set "Publiq:ClientSecret" "your-client-secret"
dotnet run

# Also create (and afterwards delete) a draft test event via the Entry API
dotnet run -- --create-event

Testing

Unit Tests vs Integration Tests

This project includes two types of tests:

  • Unit Tests: Test client creation, endpoint resolution, authentication headers, and token caching without making real API calls
  • Integration Tests: Test actual API connectivity with real servers (marked with [Trait("Category", "Integration")])

Running Tests

# Run only unit tests (CI/CD safe - no real API calls)
dotnet test --filter "Category!=Integration"

# Run all tests including integration tests (requires valid API credentials)
dotnet test

# Run only integration tests
dotnet test --filter "Category=Integration"

Configuring credentials for integration tests

The integration tests read credentials from .NET User Secrets:

cd tests/RoodFluweel.Publiq.EntryApi.Tests
dotnet user-secrets set "OAuth:ClientId" "your-client-id"
dotnet user-secrets set "OAuth:ClientSecret" "your-client-secret"

Integration tests that need credentials are skipped silently when none are configured.

CI/CD Configuration

The GitHub Actions workflow automatically excludes integration tests from CI builds to prevent issues with:

  • Network connectivity
  • API rate limits
  • Server availability
  • Missing credentials in CI environment

Integration tests should be run separately in environments with proper API access.

Generating the Client

The clients are generated from OpenAPI specifications using Kiota. To regenerate all clients, run:

./generate-client.ps1

This script will:

  1. Download OpenAPI specifications from Publiq
  2. Generate C# clients using Kiota
  3. Create project files with proper dependencies
  4. Generate client factories with authentication support

Note: the factory and .csproj files inside the src/*Api folders are regenerated (overwritten) by this script. To change them, edit the templates in generate-client.ps1.

Releasing (CI/CD)

Two GitHub Actions workflows handle CI/CD:

  • build-test.yml — every push and pull request: restore, build, and run the unit tests.
  • publish.yml — every update of main: build, test, pack the five src/ projects, and push them to nuget.org, including .snupkg symbol packages with Source Link. Can also be triggered manually (workflow dispatch). Publishing uses nuget.org Trusted Publishing (OIDC), so no long-lived API key is stored in the repository.

Published packages:

Package Contents
RoodFluweel.Publiq.Common Auth providers & environment endpoints
RoodFluweel.Publiq.EntryApi UiTdatabank Entry API client
RoodFluweel.Publiq.SearchApi UiTdatabank Search API client
RoodFluweel.Publiq.TaxonomyApi UiTdatabank Taxonomy API client
RoodFluweel.Publiq.UitpasApi UiTPAS API client

Versioning

Packages are published as {MAJOR_MINOR_VERSION}.{run number}. The run number auto-increments on every run of the publish workflow; bump the MAJOR_MINOR_VERSION variable in publish.yml for a new minor or major release (the run number keeps increasing, it does not reset). Shared package metadata (authors, license, readme, Source Link) lives in Directory.Build.props.

One-time setup (Trusted Publishing)

No API key is stored in the repository. Instead, GitHub issues a short-lived OIDC token that nuget.org exchanges for a temporary API key at publish time.

  1. On nuget.org, open the username menu → Trusted Publishing and add a policy:
    • Repository Owner: roodfluweel
    • Repository: RoodFluweel.Publiq.Client
    • Workflow File: publish.yml (file name only, no path)
  2. Add a repository secret named NUGET_USER containing your nuget.org username (your profile name, not your email) (Settings → Secrets and variables → Actions → New repository secret).

For a brand-new private-repo policy, nuget.org activates it for 7 days until the first successful publish locks it to the repository. Public repos activate immediately.

Re-running a publish workflow is safe: pushes use --skip-duplicate, so an already published version is skipped instead of failing the workflow.

Development

Building the Project

dotnet build

Packing locally

dotnet pack --configuration Release --output ./artifacts/packages

Requirements

  • .NET 8.0 or later
  • Microsoft Kiota (automatically installed by the generation script)

Documentation

For more information about the Publiq APIs, visit:

License

This project is licensed under the terms of the license included in the LICENSE file.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.2 138 6/22/2026
0.1.1 118 6/14/2026