Background
GOPACS has announced (email, April 2026) that the UFTP Participants API V2 is deprecated and will be removed starting 26 October 2026. The acceptance environment is removed first, then production. Our EMS integration in ems/manager/gopacs/ calls this API whenever Shapeshifter needs a peer's public key to verify an incoming UFTP message signature, so if we miss the deadline, inbound GOPACS messaging stops working.
The main functional change in V3 is that participants can now be looked up by ContractID + role as well as by domain, which lets GOPACS route activation messages to per-contract handlers. We are not adopting that new capability in this migration — it would require restructuring GOPACSHandler (currently one handler per EAN) and can be a follow-up if we ever need per-Capacity-Steering-Contract / per-Time-bound-Transport-Right behaviour. This migration is a minimal drop-in replacement to stay functional past the deadline.
What's changing in V3
|
V2 |
V3 |
| Base URL (prod) |
https://clc-message-broker.gopacs-services.eu |
https://api.gopacs-services.eu |
| Base URL (acc) |
n/a via our config |
https://api.acc.gopacs-services.eu |
| Participant lookup |
GET /v2/participants/DSO?contractedEan={ean} → list of all DSOs for an EAN |
GET /uftp-participants/v3/participants/{uftpDomainName} → single ParticipantView |
| Content type |
XML |
JSON |
| Auth |
(not enforced in our client) |
Bearer JWT |
| Response fields |
domain, publicKey, endpoint, … |
domain, publicKey only |
V3 also adds GET /uftp-participants/v3/participants/contracts/{contractId}/roles/{uftpRole} (roles: AGR, DSO; CRO listed as not supported). Our signature-verification call site always has the sender domain so the by-domain endpoint is the direct substitute — we don't need the contract/role endpoint for this migration.
Swagger documentation:
Scope of this change
Out of scope (follow-up if needed):
- Per-ContractID / per-role handler registration using
GET /participants/contracts/{contractId}/roles/{uftpRole}.
Deployment note
Any deployment that overrides GOPACS_PARTICIPANT_URL (for example, pinning acceptance to https://clc-message-broker-acc.gopacs-services.eu) must be updated to the new host:
- Production:
GOPACS_PARTICIPANT_URL=https://api.gopacs-services.eu (or leave unset to use the default).
- Acceptance:
GOPACS_PARTICIPANT_URL=https://api.acc.gopacs-services.eu.
Known follow-up: outbound messaging needs a broker-URL fallback
V3's ParticipantView no longer carries an endpoint field, so the cached UftpParticipantInformation stores endpoint=null. Reading shapeshifter-core 3.2.2 (and confirmed identical in 3.5.0), the outbound send path is:
GOPACSHandler.notifyNewOutgoingMessage → UftpSendMessageService.attemptToSendMessage
UftpSendMessageService.doSend (line 124–133 in 3.2.2, 135–144 in 3.5.0):
UftpParticipantInformation participantInformation = participantService.getParticipantInformation(details.recipient());
String url = participantInformation.endpoint(); // null after this migration
...
send(signedXml, url, additionalHeaders, MAX_FOLLOW_REDIRECTS);
UftpSendMessageService.send(...):
var requestBuilder = HttpRequest.newBuilder().uri(new URI(url)) ... // new URI(null) → NullPointerException
Timeline
- 25 October 2026 — last day GOPACS guarantees V2 is available.
- 26 October 2026 — GOPACS begins removing V2, starting with the acceptance environment.
Aim to have this merged and deployed to the acceptance environment well ahead of 26 October 2026 so we can validate against acceptance before production removal.
Background
GOPACS has announced (email, April 2026) that the UFTP Participants API V2 is deprecated and will be removed starting 26 October 2026. The acceptance environment is removed first, then production. Our EMS integration in
ems/manager/gopacs/calls this API whenever Shapeshifter needs a peer's public key to verify an incoming UFTP message signature, so if we miss the deadline, inbound GOPACS messaging stops working.The main functional change in V3 is that participants can now be looked up by ContractID + role as well as by domain, which lets GOPACS route activation messages to per-contract handlers. We are not adopting that new capability in this migration — it would require restructuring
GOPACSHandler(currently one handler per EAN) and can be a follow-up if we ever need per-Capacity-Steering-Contract / per-Time-bound-Transport-Right behaviour. This migration is a minimal drop-in replacement to stay functional past the deadline.What's changing in V3
https://clc-message-broker.gopacs-services.euhttps://api.gopacs-services.euhttps://api.acc.gopacs-services.euGET /v2/participants/DSO?contractedEan={ean}→ list of all DSOs for an EANGET /uftp-participants/v3/participants/{uftpDomainName}→ singleParticipantViewdomain,publicKey,endpoint, …domain,publicKeyonlyV3 also adds
GET /uftp-participants/v3/participants/contracts/{contractId}/roles/{uftpRole}(roles:AGR,DSO;CROlisted as not supported). Our signature-verification call site always has the sender domain so the by-domain endpoint is the direct substitute — we don't need the contract/role endpoint for this migration.Swagger documentation:
Scope of this change
GOPACSAddressBookResourceto the V3 by-domain endpoint (JSON, Authorization header).ParticipantViewDTO record mirroring the V3 response schema.GOPACSHandler.getParticipantInformation(...)to call the V3 endpoint with a Bearer token from the existing OAuth2 client-credentials flow. Extract the token acquisition into a sharedfetchBearerToken()helper.DEFAULT_GOPACS_PARTICIPANT_URLtohttps://api.gopacs-services.eu.endpointfield from cachedUftpParticipantInformation(V3 no longer returns it — we passnull).Out of scope (follow-up if needed):
GET /participants/contracts/{contractId}/roles/{uftpRole}.Deployment note
Any deployment that overrides
GOPACS_PARTICIPANT_URL(for example, pinning acceptance tohttps://clc-message-broker-acc.gopacs-services.eu) must be updated to the new host:GOPACS_PARTICIPANT_URL=https://api.gopacs-services.eu(or leave unset to use the default).GOPACS_PARTICIPANT_URL=https://api.acc.gopacs-services.eu.Known follow-up: outbound messaging needs a broker-URL fallback
V3's
ParticipantViewno longer carries anendpointfield, so the cachedUftpParticipantInformationstoresendpoint=null. Readingshapeshifter-core3.2.2 (and confirmed identical in 3.5.0), the outbound send path is:GOPACSHandler.notifyNewOutgoingMessage→UftpSendMessageService.attemptToSendMessageUftpSendMessageService.doSend(line 124–133 in 3.2.2, 135–144 in 3.5.0):UftpSendMessageService.send(...):Timeline
Aim to have this merged and deployed to the acceptance environment well ahead of 26 October 2026 so we can validate against acceptance before production removal.