> For the complete documentation index, see [llms.txt](https://experience-digital-transform.gitbook.io/experience-digital-transformation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://experience-digital-transform.gitbook.io/experience-digital-transformation/gif/module-5-implementation-and-onboarding/5.6-run-the-once-only-exchange-live.md).

# 5.6 Run the once-only exchange, live

PNEA issues a credential and pre-fills identity from PNIA and enrolment from PLR — a real cross-server call, the data asked once.

{% embed url="<https://youtu.be/_6F_eXrJNSY>" %}
The live once-only exchange: a government framework proven in one real call (\~3 min)
{% endembed %}

**Watch first (\~3 min).** Then come back for the play.

> **Single message.** PNEA issues a credential and pre-fills identity from PNIA and enrolment from PLR — a real cross-server call, the data asked once.

## The concept

This is the exchange the whole framework exists for: the examination authority issues a credential and fetches the learner's identity and enrolment itself, asking the learner once. What follows was recorded from the running federation.

This is the call on screen. The examination authority, PNEA, receives a learner's credential application. Without once-only, PNEA would ask the learner for paper proof of identity and of enrolment. With it, PNEA fetches the identity from the identity authority, PNIA, and the enrolment from the learner registry, PLR, over the bus.

First, the form before and after the call. Before, ten rows, all blank: ten questions the learner answers, and two sets of paper proof. Once PNEA has the learner's national ID, nine rows fill in: five from the identity authority, PNIA, four from the learner registry, PLR, each labelled with its source. One question asked, nine fetched.

Second, the second tab reads the exchange by layer. In the legal pane, the identity authority, PNIA, sends five fields and names three it holds but withholds: a mother's name, a birth registration number, an address. The purpose does not need them.

Third, permission. Asked the identical question, the examination authority, PNEA, is allowed, and the learner registry, PLR, is refused by the identity authority's access list. Then the operator withdraws the examination authority's permission: within seconds the identity rows are denied while the enrolment rows still fill. Restore it, and the form is whole. Being on the bus is not permission.

Fourth, the record and the proof. The exchange is written to disk as the assembled application, one line per field with its source; the national ID is the only line the citizen supplied. And the acceptance script runs the exchange as six checks: the call, the right learner, asked once, the denial, a clean not-found, and field conformance. All six pass: the technical half of go-live approval.

## Your turn — Script and verify the once-only exchange (the acceptance check)

{% hint style="success" %}
**✍️ Drafting play · produces B33 Once-only acceptance script**

**Bring:** the Progressa once-only scenario and the federation. From **B32, B27** (see [Your framework workbook](/experience-digital-transformation/gif/your-framework-workbook.md)). **Get:** a given/when/then acceptance script with a negative check, mapped to the four layers. As text in the chat, not a file or a chart. **Time:** \~20 min · **Assistant:** any; the plays are tool-neutral. **With the kit:** no skill in this release, so the prompt runs bare in any assistant. **Watch for:** An acceptance check that only proves the happy path is half a check — include the negative case (an unauthorised member is denied) and confirm the data returned is the right learner's, not merely that data returned.
{% endhint %}

✍️ **Drafting play.** You give a few facts; the play produces a first draft of a document you will edit.

**What it does.** An architect needs to script the once-only demonstration exchange and its acceptance check — the call, the expected result, and the proof that the learner is asked once. This prompt produces the acceptance script.

{% tabs %}
{% tab title="Prompt" %}
Copy the prompt, replace the bracketed parts with your own context, and run it in the AI assistant of your choice. Never paste personal data or unpublished documents — see [How to use the plays](https://experience-digital-transform.gitbook.io/experience-digital-transformation/government-enterprise-architecture-gea/developing-a-gov-enterprise-architecture-gea/start-here/how-to-use-the-plays).

```
Script the once-only acceptance check for [country X] / Progressa's interoperability demonstration. The scenario: a learner applies for a credential at the examination authority (PNEA), which pre-fills identity from the identity authority (PNIA) and enrolment from the learner registry (PLR) over the X-Road bus. Produce: (1) the GIVEN — the federation deployed, the four members registered, the service published, the demonstration data seeded; (2) the WHEN — the exact cross-server call(s) PNEA makes to PNIA and PLR; (3) the THEN — the expected result: identity and enrolment returned over the bus, the learner asked once, no paper re-entry; (4) the negative check — that a member NOT authorised by the access-control list cannot make the call. Map each step to the layer it exercises (technical/legal/organisational/semantic). Mark every identifier and endpoint as [confirm: against the live registry]. Output: the given/when/then acceptance script plus the negative check.
```

[Open in Claude](https://claude.ai/new?q=Script%20the%20once-only%20acceptance%20check%20for%20%5Bcountry%20X%5D%20%2F%20Progressa%27s%20interoperability%20demonstration.%20The%20scenario%3A%20a%20learner%20applies%20for%20a%20credential%20at%20the%20examination%20authority%20%28PNEA%29%2C%20which%20pre-fills%20identity%20from%20the%20identity%20authority%20%28PNIA%29%20and%20enrolment%20from%20the%20learner%20registry%20%28PLR%29%20over%20the%20X-Road%20bus.%20Produce%3A%20%281%29%20the%20GIVEN%20%E2%80%94%20the%20federation%20deployed%2C%20the%20four%20members%20registered%2C%20the%20service%20published%2C%20the%20demonstration%20data%20seeded%3B%20%282%29%20the%20WHEN%20%E2%80%94%20the%20exact%20cross-server%20call%28s%29%20PNEA%20makes%20to%20PNIA%20and%20PLR%3B%20%283%29%20the%20THEN%20%E2%80%94%20the%20expected%20result%3A%20identity%20and%20enrolment%20returned%20over%20the%20bus%2C%20the%20learner%20asked%20once%2C%20no%20paper%20re-entry%3B%20%284%29%20the%20negative%20check%20%E2%80%94%20that%20a%20member%20NOT%20authorised%20by%20the%20access-control%20list%20cannot%20make%20the%20call.%20Map%20each%20step%20to%20the%20layer%20it%20exercises%20%28technical%2Flegal%2Forganisational%2Fsemantic%29.%20Mark%20every%20identifier%20and%20endpoint%20as%20%5Bconfirm%3A%20against%20the%20live%20registry%5D.%20Output%3A%20the%20given%2Fwhen%2Fthen%20acceptance%20script%20plus%20the%20negative%20check.) *(experimental deep link: pre-fills the prompt in a new claude.ai chat; check the bracketed parts before sending)*

*Input, output and the kit skill are in the box above.*
{% endtab %}

{% tab title="Example input" %}
{% hint style="warning" %}
**Draft worked example, 2026-10-04.** A bare run on Progressa, annotated, but not yet checked against the kit's expected output. Read it with the annotations, not on its own.
{% endhint %}

The bracketed context in the prompt was replaced with the following:

**\[country X]:** Progressa.

**From the federation run book (B32), in short:** a Central Server run by PDGA, the federation owner (`PROGRESSA/GOV/PDGA`). Four security servers: `ss-pdga`, `ss-pnea`, `ss-plr`, `ss-pnia`. A Test CA with OCSP and time-stamping. Three members: `PROGRESSA/GOV/PNEA:EXAMS` (the consumer), `PROGRESSA/GOV/PLR:ENROLMENT` (publishes `enrolment-api`) and `PROGRESSA/GOV/PNIA:IDENTITY` (publishes `identity-api`). The stand-up ends when every member appears in the Central Server registry. Synthetic learner data is then seeded into the two registries.

**From the data-protection envelope (B27), in short:** `identity-api` returns the NIN, given name, family name, date of birth, sex and region. It holds a mother's name, a birth registration number and an address, and does not return them. Only `PNEA:EXAMS` may call it. Lawful basis: a purpose-limited person lookup for issuing a credential (illustrative wording). `enrolment-api` returns school, level, enrolment year and status.
{% endtab %}

{% tab title="Example output" %}
{% hint style="warning" %}
**Draft: model output, unverified.** Read it with the annotations in the next tab, not on its own.
{% endhint %}

{% hint style="info" %}
**In the build pack.** The Progressa version of this artefact is a real file, not a pasted draft: `acceptance/once-only-exchange.md`, `scripts/acceptance.sh`, `out/application-<nin>.json` — see [What the build pack is](/experience-digital-transformation/gif/the-build-pack.md).
{% endhint %}

**GIVEN** (technical, organisational): the federation is deployed and every member is registered. Both services are published with their access rights. Synthetic data is seeded, and the test picks a NIN that exists in both PNIA's and PLR's data. Every identifier below is *\[confirm: against the live registry]*.

**WHEN** (technical): PNEA makes two calls through its own security server.

```
GET https://ss-pnea:2443/r1/PROGRESSA/GOV/PNIA/IDENTITY/identity-api/persons/{nin}
    X-Road-Client: PROGRESSA/GOV/PNEA/EXAMS
GET https://ss-pnea:2443/r1/PROGRESSA/GOV/PLR/ENROLMENT/enrolment-api/enrolments/{nin}
    X-Road-Client: PROGRESSA/GOV/PNEA/EXAMS
```

**THEN**

| # | Check                       | Passes when                                                                                                                                                                | Layer                 |
| - | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| 1 | Happy path                  | Both calls return 200, routed server to server (`ss-pnea` to `ss-pnia` and `ss-plr`)                                                                                       | technical             |
| 2 | Right learner               | Every returned field equals the seeded record for that NIN                                                                                                                 | semantic              |
| 3 | Asked once                  | The assembled application holds one field from the citizen (the NIN) and nine from the bus. No field is keyed twice                                                        | organisational, legal |
| 4 | Only what the purpose needs | The identity response has its six fields and none of the three withheld ones                                                                                               | legal                 |
| 5 | Negative                    | The same identity call, sent as `PROGRESSA/GOV/PLR/ENROLMENT` through `ss-plr`, is refused by PNIA's access list with an X-Road access-denied fault, not a transport error | organisational        |

**Evidence:** `out/application-{nin}.json`, the assembled application with the source of each field.
{% endtab %}

{% tab title="Reading the output" %}
This is the teaching part of the play. Work through the output the way a chief architect would — what is earned, what is invented, what is missing.

<details>

<summary>1. The negative check tests the right thing</summary>

PLR is a member of the bus and publishes a service of its own, so its refusal shows that the access list did the work, not membership. The script also requires the refusal to come from PNIA's side as an access-denied fault. A timeout would look like a pass but prove nothing. The build pack's acceptance file records this denial as the X-Road fault `Server.ServerProxy.AccessDenied`.

</details>

<details>

<summary>2. "Legal" on check 3 is overstated</summary>

The script builds the application file and then checks that file. That proves no field was keyed twice in this form. It does not prove the learner was not asked on paper somewhere else. Check 4 tests that the response leaves out the withheld fields, but nothing in the script can test whether the lawful basis is real, and in the pack that wording is illustrative. Call the legal layer "enforced as configured", not "proven".

</details>

<details>

<summary>3. Two cases are missing</summary>

First, a NIN that PNIA holds and PLR does not should return the identity and a clean 404 from the enrolment service. A silent empty answer must not pass. Second, a plain-HTTP call to PNEA's security server should be refused, because PNEA's connection is set to HTTPS. The pack's script runs the first case as one of its six checks. Its acceptance file records the second refusal, but the script does not test it.

</details>

{% hint style="danger" %}
**Safeguard for this play.** An acceptance check that only proves the happy path is half a check — include the negative case (an unauthorised member is denied) and confirm the data returned is the right learner's, not merely that data returned. Run it against the sandbox federation, and treat a passing check as proof for this exchange only, not a guarantee for exchanges you have not tested.
{% endhint %}
{% endtab %}

{% tab title="What next" %}
This script is where the chain ends. Compare it with the pack's own version on [The acceptance check](/experience-digital-transformation/gif/the-build-pack/acceptance-the-once-only-proof.md) and add the two missing cases before you run it on your sandbox federation. A pass proves this one exchange and nothing more. Then take the federation that passed into the production gap in [5.7](/experience-digital-transformation/gif/module-5-implementation-and-onboarding/5.7-from-demonstration-to-production.md). In your framework workbook this is artefact **B33**.

**This artefact feeds:** nothing further in this course; this artefact is where the chain ends

See the full chain in [Your framework workbook](/experience-digital-transformation/gif/your-framework-workbook.md).
{% endtab %}
{% endtabs %}

## Sources

* PAERA v1.0 §5.2 (Once-Only) — <https://paera.govstack.global>
* NIIS X-Road — <https://docs.x-road.global>
* the build-pack acceptance check — in this knowledge base: [acceptance](/experience-digital-transformation/gif/the-build-pack/acceptance-the-once-only-proof.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://experience-digital-transform.gitbook.io/experience-digital-transformation/gif/module-5-implementation-and-onboarding/5.6-run-the-once-only-exchange-live.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
