AssinaJa.PublicApi.Client
1.1.0
dotnet add package AssinaJa.PublicApi.Client --version 1.1.0
NuGet\Install-Package AssinaJa.PublicApi.Client -Version 1.1.0
<PackageReference Include="AssinaJa.PublicApi.Client" Version="1.1.0" />
<PackageVersion Include="AssinaJa.PublicApi.Client" Version="1.1.0" />
<PackageReference Include="AssinaJa.PublicApi.Client" />
paket add AssinaJa.PublicApi.Client --version 1.1.0
#r "nuget: AssinaJa.PublicApi.Client, 1.1.0"
#:package AssinaJa.PublicApi.Client@1.1.0
#addin nuget:?package=AssinaJa.PublicApi.Client&version=1.1.0
#tool nuget:?package=AssinaJa.PublicApi.Client&version=1.1.0
AssinaJá Public API Client
Official .NET client for the AssinaJá public API — electronic and qualified signatures under eIDAS, including the Portuguese Chave Móvel Digital.
Generated from the published OpenAPI contract, so it matches the server by construction.
Install
dotnet add package AssinaJa.PublicApi.Client
Targets netstandard2.0 and netstandard2.1. Depends on Newtonsoft.Json — see the 0.2.0 note
below for why that is a requirement, not a leftover.
Authentication
Every request carries your organization API key in the X-Api-Key header:
// Two namespaces: the helper lives in .Client, the generated clients and models in .Models.
using AssinaJa.PublicApi.Client;
using AssinaJa.PublicApi.Client.Models;
var http = new HttpClient();
PublicApiHelper.SetupHttpClient(http, "https://app.assinaja.pt", apiKey);
var templates = new AssinaJaPublicTemplateClient(http);
// signerId and x_Api_Key_TemplateCatalog are both optional — pass null unless you are
// listing on behalf of a signer, or reading another organization's template catalog.
var page = await templates.GetPaginatedAsync(
null, null, new PaginatedRequestQuery { PageNumber = 1, PageSize = 20 });
foreach (var t in page.Items)
Console.WriteLine($"{t.Id} {t.TemplateName} ({t.TemplateKind})");
A key holds an explicit list of scopes and can only do what is ticked. A missing scope is a
403, and the required scope for each route is on the operation's XML docs (visible in IntelliSense)
and in the published contract as x-required-scopes. Nine scopes exist; documents:write and
templates:read are the usual starting pair.
What it covers
Templates (PDF and DOCX), document creation and publishing, signer progress, downloading the signed PDF and its completion report, upload links, the organization with its plan and quotas, and the webhook signing secret.
License
MIT — this generated client only. It grants no rights over the AssinaJá service itself, which is governed by its own terms.
1.0.1
Every route now declares 429. Rate limiting was extended from the creation routes to the whole
public API, with a deliberately generous ceiling on reads — an integrator paginating hard should
never see it. The contract declares 429 with its body (retryAfterSeconds) on all 26 operations,
so a regenerated client can read it. Handle it with a backoff even where you have never seen one:
the ceiling exists on every route now. No method signatures changed.
1.0.0 — first release on nuget.org
This is the first version of this package published on nuget.org. Earlier versions (0.1.0,
0.2.0) only ever existed as a copy inside a partner's private feed, which AssinaJá could neither
update nor control. If you are upgrading from one of those, everything below applies to you; if you
are starting here, it is just release notes.
Some generated methods gained a parameter. Idempotency-Key and X-Api-Key-TemplateCatalog were
read from the raw request on the server but never declared in the contract, so a generated client had
no way to send either one. They are now declared header parameters, which changes the signature of
the methods on the affected routes:
// before (0.2.0)
await templates.GetTemplateDetailsAsync(templateId);
// after (1.0.0) — pass null when you are using your own template catalog
await templates.GetTemplateDetailsAsync(templateId, null);
New: read and rotate your webhook signing secret (AssinaJaPublicWebhookSecretClient, scope
webhooks:secret). Until now there was no way to obtain it over the API at all, and without it
webhook deliveries cannot be verified:
var secrets = new AssinaJaPublicWebhookSecretClient(http);
var s = await secrets.GetAsync(); // "" when none has been generated yet — a 200, not a 404
if (string.IsNullOrEmpty(s.Secret))
s = await secrets.RotateAsync(); // creates the first one
Verify a delivery by computing HMAC-SHA256 over "{X-AssinaJa-Timestamp}.{raw body}", keyed on the
base64url-decoded bytes of that secret; the expected X-AssinaJa-Signature is v1= plus the
lowercase hex digest. During a 24-hour rotation window the header carries two comma-separated
signatures and a match on either is valid.
If you implemented webhook validation against an older specification, it never worked. That document said to sign with the organization's
licenseKeyin the formsha256=HMAC-SHA256(licenseKey, body). ThelicenseKeyis a different value and signing with it never validates.
Listings refuse what they cannot do, instead of ignoring it. filters and sort on the public
listings used to answer 500 for an enum field and — worse — 200 over an unfiltered page for a
field name that did not exist. Enum fields now work, and an unknown field or value is a 400 naming
what is valid. The same applies to POST /Document/list in the ToSign/Received scopes, which
silently discarded everything it could not translate.
Also declared, so generated clients can see them: 401, 403, 429 and 500 on every route,
402 with its quota body, binary bodies on the file routes, and a typed 200 on
POST /templates/{id}/documents (it previously declared no schema, so the client discarded the id of
the document it had just created).
0.2.0 breaking change
Verified against the code on 2026-08-26 (version 2.5.23, branch
fix/public-api-templates-contract@8ee3cebce).
Upgrade if you touch templates. Versions before 0.2.0 cannot deserialize the current template
responses at all: the published spec declared every enum as an integer while the server has always
written strings, and optional enums were not marked nullable — so both null and "Everyday" threw.
Three changes, in order of what will break your build:
1. The template model changed shape. TemplateDetailsPublicModel:
| Before | Now |
|---|---|
MergeFields — IDictionary<string, string>, and always empty for a DOCX template |
MergeFields — List<TemplateMergeFieldPublicModel> (Name, Required, Active, Source), populated for both kinds |
SignerRecipients — always empty for a DOCX template |
Signers — List<TemplateSignerPublicModel>, one array for both kinds |
| — | TemplateKind (TemplateKindEnum.Pdf / .Docx) and Status (DocumentStatusEnum?) |
GetTemplateSignersAsync returned List<TemplateSignerShortcutModel> (with AllowedSignatureTypes, a list that always had one element) |
returns TemplateSignersPublicModel — { TemplateKind, Signers }, with SignatureType singular |
Exactly one signer identifier is populated, and TemplateKind says which — Pdf ⇒ Code,
Docx ⇒ Id (the N of the {{AssinaJa_N_TYPE}} markers, which no public route used to expose):
var t = await templates.GetTemplateDetailsAsync(2483, null); // null = use your own template catalog
var payload = t.TemplateKind == TemplateKindEnum.Docx
? t.Signers.Select(s => new DocxTemplateSignerModel { Id = s.Id!.Value, Nome = …, Email = … })
: throw new InvalidOperationException("PDF template: send Signers[].Code to Document/Create instead.");
Every reference-typed property on the generated models is optional (Required.Default), so the
compiler will not stop you from enumerating a null collection — guard before you do.
2. Enums travel as strings, and the client now speaks Newtonsoft.Json. The package depends on
Newtonsoft.Json (13.0.4) instead of System.Text.Json. It had to: FilterOperator carries wire values
that are not C# identifiers ("=", ">=", "Contains") through [EnumMember], and
System.Text.Json ignores [EnumMember] entirely. EnumSerializationDefaults.cs registers Newtonsoft's
StringEnumConverter on every generated client class through NSwag's UpdateJsonSerializerSettings
extension point, so it survives regeneration. Without it the client wrote enums as integers and the
server rejected them (AllowIntegerValues = false) — every filtered listing came back 400.
3. Two new refusals to handle. 423 Locked with FEATURE_TEMPLATES_NOT_ENABLED when the plan of the
organization that serves the template does not include Templates — distinct from 403 (the key lacks
the scope) and from 401 (the key itself is not good). Drafts are no longer listed, and the detail of a
draft is 404 TEMPLATE_NOT_FOUND.
Full guide, with request/response examples: docs/using_templates.md (§4 discovery, §10 what breaks).
0.1.0 breaking change
PublicApiHelper.SetupHttpClient now takes a single apiKey argument instead of the old
apiKeySubscription/apiKeyEmail pair — the legacy x-api-subscription-id/x-api-email
headers have been removed entirely. Migration:
// before (0.0.x)
PublicApiHelper.SetupHttpClient(httpClient, baseUrl, apiKeySubscription, apiKeyEmail);
// after (0.1.0)
PublicApiHelper.SetupHttpClient(httpClient, baseUrl, apiKey);
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Newtonsoft.Json (>= 13.0.4)
-
.NETStandard 2.1
- Newtonsoft.Json (>= 13.0.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.