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
<PackageReference Include="RoodFluweel.Publiq.EntryApi" Version="0.2.2" />
<PackageVersion Include="RoodFluweel.Publiq.EntryApi" Version="0.2.2" />
<PackageReference Include="RoodFluweel.Publiq.EntryApi" />
paket add RoodFluweel.Publiq.EntryApi --version 0.2.2
#r "nuget: RoodFluweel.Publiq.EntryApi, 0.2.2"
#:package RoodFluweel.Publiq.EntryApi@0.2.2
#addin nuget:?package=RoodFluweel.Publiq.EntryApi&version=0.2.2
#tool nuget:?package=RoodFluweel.Publiq.EntryApi&version=0.2.2
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:
- Download OpenAPI specifications from Publiq
- Generate C# clients using Kiota
- Create project files with proper dependencies
- Generate client factories with authentication support
Note: the factory and
.csprojfiles inside thesrc/*Apifolders are regenerated (overwritten) by this script. To change them, edit the templates ingenerate-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 fivesrc/projects, and push them to nuget.org, including.snupkgsymbol 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.
- 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)
- Repository Owner:
- Add a repository secret named
NUGET_USERcontaining 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 | Versions 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. |
-
net8.0
- Microsoft.Kiota.Abstractions (>= 2.0.0)
- Microsoft.Kiota.Http.HttpClientLibrary (>= 2.0.0)
- Microsoft.Kiota.Serialization.Form (>= 2.0.0)
- Microsoft.Kiota.Serialization.Json (>= 2.0.0)
- Microsoft.Kiota.Serialization.Multipart (>= 2.0.0)
- Microsoft.Kiota.Serialization.Text (>= 2.0.0)
- RoodFluweel.Publiq.Common (>= 0.2.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.