# How to constrain DV\_CODED\_TEXT to a SNOMED CT ECL query

**URL:** https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017
**Category:** Archetype Designer
**Created:** [13 June 2026 14:05 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017 "2026-06-13T14:05:31Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![henrydwright](https://discourse.openehr.org/user_avatar/discourse.openehr.org/henrydwright/32/5330_2.png) [@henrydwright](https://discourse.openehr.org/u/henrydwright)
#### Post date: [13 June 2026 14:05 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/1 "2026-06-13T14:05:32Z")

</div>

I am fairly new to the modelling side of OpenEHR and am trying to use the Archetype Designer to avoid creating my archetype/template by hand, though if the tool is the constraint I am happy to modify by hand or using SDKs as needed.

Essentially I want to know the correct way to go about having a DV\_CODED\_TEXT constrained to some SNOMED CT ECL query - as an example ‘^999003051000000109’

I have tried constraining to external coded, binding to SNOMED-CT and putting in ‘ecl/^999003051000000109’ but a) am not sure if that is correct to include ‘ecl’/’ and b) this all disappears in the OPT of the template created from the archetype

In Archetype Designer…

 ![image](https://discourse.openehr.org/uploads/default/original/2X/4/40cda362370b8c8f02183e802a2cac513f051cf2.png)

In Archetype ADL…

 ![image](https://discourse.openehr.org/uploads/default/original/2X/2/2fade4042374501ba71aaf4cf71b1d51dffc1ce8.png)

In Template… (gone! and no constraints generated separately)

 ![image](https://discourse.openehr.org/uploads/default/original/2X/b/b09a63d242eb1c00dbd24b519b6896118ec45437.png)

---

<div class="post-metadata">

### Author: ![ian.mcnicoll](https://discourse.openehr.org/user_avatar/discourse.openehr.org/ian.mcnicoll/32/4430_2.png) [@ian.mcnicoll](https://discourse.openehr.org/u/ian.mcnicoll)
#### Post date: [13 June 2026 19:46 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/2 "2026-06-13T19:46:13Z")

</div>

This should be possible via a FHIR Valueset interface.

We generally do not set these kind of constraints in archetypes but rather in templates.

Select External coded, then Query and then from Browse server -\>Add Custom terminology and enter this as the terminology string

`terminology://fhir.hl7.org/ValueSet/$expand?url=[http://snomed.info/sct?fhir\_vs=ecl/^999003051000000109\`](http://snomed.info/sct?fhir_vs=ecl/%5E999003051000000109%5C%60)

`terminology://fhir.hl7.org` is just an internal namespace that signifies that the next part of the string is a FHIR service.

`ValueSet/$expand?url=http://snomed.info/sct?fhir_vs=ecl/^999003051000000109` is standard FHIR Valueset handling for a SNOMED ECL command.

You will need to hook up your CDR to the FHIR terminology server via the CDR config. See [Terminology Validation | EHRbase Docs](https://docs.ehrbase.org/docs/EHRbase/Explore/Terminology) for ehrBase

---

<div class="post-metadata">

### Author: ![erik.sundvall](https://discourse.openehr.org/user_avatar/discourse.openehr.org/erik.sundvall/32/1961_2.png) [@erik.sundvall](https://discourse.openehr.org/u/erik.sundvall)
#### Post date: [15 June 2026 08:16 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/3 "2026-06-15T08:16:24Z")

</div>

Great that you bring this up @henrydwright, and thanks for response @ian.mcnicoll

I have asked similar questione earlier in the openEHR SEC years ago “how do we represent post-coordinated SNOMED CT ecpressionr in opneEHR?” - but then did not follow up. I do think there will be cases when we actually do want to use ECL in archetypes (but likley more often in Templates or forms).

Storing postccordinated SNOMED CT “scentences”/expressions is one use. Value set expansions is another one.

We should also think about standardizing a way to at a coarse level of an archetype/template be able to, in data instances (COMPOSITIONs etc), “build” post-cordinated SNOMED CT expressions from the selections picked (e.g. at runtime) in more granular parts of the archetype/template. Perhaps ECL with variable/path-expressions could work for this?

Pinging @mikael & @Daniel_Karlsson thay usually have thoughts regarding such tnings…

---

<div class="post-metadata">

### Author: ![henrydwright](https://discourse.openehr.org/user_avatar/discourse.openehr.org/henrydwright/32/5330_2.png) [@henrydwright](https://discourse.openehr.org/u/henrydwright)
#### Post date: [15 June 2026 19:45 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/4 "2026-06-15T19:45:47Z")

</div>

Thanks @ian.mcnicoll why the FHIR inclusion in the URL given that presumably one could have a non-FHIR terminology server that supports SNOMED CT?

Would it not be `http://snomed.info/sct?fhir_vs=ecl/^999003051000000109` which ends up in the OPERATIONAL\_TEMPLATE within the `<referenceSetUri>` tags?

---

<div class="post-metadata">

### Author: ![yampeku](https://discourse.openehr.org/user_avatar/discourse.openehr.org/yampeku/32/25_2.png) [@yampeku](https://discourse.openehr.org/u/yampeku)
#### Post date: [16 June 2026 10:04 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/5 "2026-06-16T10:04:46Z")

</div>

You can use snomed-ct uris if you want, it’s basically the ecl encoded for being sent as an uri  
For example:  
404684003 **|Clinical finding** |: 47429007 **|Associated with** | = 79654002\*\*| **Edema** |\*\* ends up as URI [http://snomed.info/scg/404684003%3A47429007%3D79654002](http://snomed.info/scg/404684003%3A47429007%3D79654002)

you have more examples here

> **[SNOMED CT URI Standard - SNOMED CT Languages Project Group - SNOMED Spaces](https://conf.spaces.snomed.org/wiki/spaces/SLPG/pages/130985988/SNOMED+CT+URI+Standard)**

---

<div class="post-metadata">

### Author: ![ian.mcnicoll](https://discourse.openehr.org/user_avatar/discourse.openehr.org/ian.mcnicoll/32/4430_2.png) [@ian.mcnicoll](https://discourse.openehr.org/u/ian.mcnicoll)
#### Post date: [16 June 2026 11:00 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/6 "2026-06-16T11:00:56Z")

</div>

> [@henrydwright](#):
>
> [http://snomed.info/sct?fhir\_vs=ecl/^999003051000000109](http://snomed.info/sct?fhir_vs=ecl/%5E999003051000000109)

No, you need the terminology://fhir.hl7.org to let the CDR know that you are trying to talk to a FHIR terminology service and not some other proprietary service. In practice, the `terminology://fhir.hl7.org’ will be substituted at runtime by the physical endpoint that is hooked up to the CDR e,g

[https://ontoserver.nhs.uk/fhir/ValueSet/$expand?url=http://snomed.info/sct?fhir\_vs=ecl/^999003051000000109](https://ontoserver.nhs.uk/fhir/ValueSet/$expand?url=http://snomed.info/sct?fhir_vs=ecl/%5E999003051000000109)

The problem with SNOMED is that there is no standard API - each terminlogy service has its own variation. What FHIR introduced was a vendor-neutral interface - even SNOMED itself recommends using FHIR.

> **[Is there a SNOMED API? | Implementation Guides Implementation Fact Sheets |...](https://docs.snomed.org/implementation-guides/implementation-fact-sheets/technology-adoption/is-there-a-snomed-api)**

You absolutely could talk directly to a SNOMED service (not sure if that is the exact syntax, perhaps @yampeku could advise?.)

However you then have the problem of hooking your CDR up directly to that SNOMED API service, which may or may not be supported or standardised

Strategically, I would always advise going via FHIR to maximise vendor-neutrality, and TBH you are almost certainly going to need support for terminologies other than SNOMED.

---

<div class="post-metadata">

### Author: ![yampeku](https://discourse.openehr.org/user_avatar/discourse.openehr.org/yampeku/32/25_2.png) [@yampeku](https://discourse.openehr.org/u/yampeku)
#### Post date: [16 June 2026 11:15 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/7 "2026-06-16T11:15:16Z")

</div>

In principle FHIR terminology stack can support both, as they can point to ?fhir\_vs=ecl/ and use the query as is

In the end is knowing if your fhir server supports it

---

<div class="post-metadata">

### Author: ![borut.jures](https://discourse.openehr.org/user_avatar/discourse.openehr.org/borut.jures/32/1391_2.png) [@borut.jures](https://discourse.openehr.org/u/borut.jures)
#### Post date: [16 June 2026 17:24 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/8 "2026-06-16T17:24:30Z")

</div>

> [@ian.mcnicoll](#):
>
> No, you need the terminology://fhir.hl7.org to let the CDR know that you are trying to talk to a FHIR terminology service and not some other proprietary service.

I like Henry’s thinking - why force a FHIR terminology server into the SNOMED-CT term bindings? What if something like [Hermes](https://github.com/wardle/hermes) is used instead of FHIR server.

The description of `ARCHETYPE_TERMINOLOGY.term_bindings` defines `Uri` as:

> The indexed `Uri` objects represent references to externally defined resources, either terms, ontology concepts, or terminology subsets / ref-sets.

The description doesn’t mention that `Uri` can hold implementation details and FHIR server is not one of the 4 allowed external resources. I would expect that `Uri` should start with `http://snomed.info/sct` (some tools validate that `Uri` must be a valid SNOMED uri for `SNOMED_CT` terminology ids).

I expect that at some point in the past, a requirement arose to use post-coordinated SNOMED-CT expressions, and the quick&dirty fix was to use the FHIR terminology server URI.

It works but it smells like a hack. openEHR CDR could implement support for SNOMED-CT post-coordinated expressions or allow configuration settings for external services (where a FHIR terminology server can be configured for `SNOMED_CT` terminology id).

A problem with quick&dirty fixes is that “quick” is forgotten and only “dirty” remains.

I agree with @henrydwright that `http://snomed.info/sct?fhir_vs=ecl/^999003051000000109` should be used as term binding Uri and the CDR should use it as part of the full url for the configured server. For example `http://localhost:8080/fhir/ValueSet/$expand?url=http://snomed.info/sct?fhir_vs=ecl%2F%5E999003051000000109&count=20&includeDesignations=true&filter=append`.

SNOMED docs: [Using a Terminology-server | Implementation Guides SNOMED IPS Terminology Implementation Guide | SNOMED International Documents](https://docs.snomed.org/implementation-guides/snomed-ips-terminology-implementation-guide/3-using-a-terminology-server#valueset.usdexpand)

---

<div class="post-metadata">

### Author: ![birger.haarbrandt](https://discourse.openehr.org/user_avatar/discourse.openehr.org/birger.haarbrandt/32/24_2.png) [@birger.haarbrandt](https://discourse.openehr.org/u/birger.haarbrandt)
#### Post date: [18 June 2026 05:13 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/9 "2026-06-18T05:13:52Z")

</div>

Hi all,

if I remember correctly, it has become quite a standard practice in Germany to express these things like ECL within a FHIR ValueSet. In General, it’s quite uncommon to directly reference a terminology without a valueSet constraint. So I can second what @ian.mcnicoll is saying. I don’t think its dirty, its how standardization works and FHIR Terminology Service is the only thing that I know that actually finds some adoption in reality in this area.

---

<div class="post-metadata">

### Author: ![borut.jures](https://discourse.openehr.org/user_avatar/discourse.openehr.org/borut.jures/32/1391_2.png) [@borut.jures](https://discourse.openehr.org/u/borut.jures)
#### Post date: [18 June 2026 06:46 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/10 "2026-06-18T06:46:33Z")

</div>

Using [http://snomed.info/sct?fhir\_vs=ecl/^999003051000000109](http://snomed.info/sct?fhir_vs=ecl/%5E999003051000000109) in term bindings still allows embedding it in a call to a FHIR terminology server:

http://localhost:8080/fhir/ValueSet/$expand?url=_ **http://snomed.info/sct?fhir\_vs=ecl%2F%5E999003051000000109** _&count=20&includeDesignations=true&filter=append

Why not use a “cleaner” (or at least shorter) version?

* * *

I searched where `terminology://` is explained in the specifications. I found this example in [AQL](https://specifications.openehr.org/releases/QUERY/development/AQL.html#_matches) using `terminology://snomed-ct`:

`terminology://snomed-ct/hierarchy?rootConceptId=50043002`

However in [AQL Examples](https://specifications.openehr.org/releases/QUERY/development/AQL_examples.html#_terminology) the `terminology://fhir.hl7.org` variant is used for SNOMED-CT.

Why not use `terminology://snomed-ct` instead of `terminology://fhir.hl7.org`?

I couldn’t find where the use of `terminology://` is described in the specifications. Can somebody point me to the right specifications?

---

<div class="post-metadata">

### Author: ![birger.haarbrandt](https://discourse.openehr.org/user_avatar/discourse.openehr.org/birger.haarbrandt/32/24_2.png) [@birger.haarbrandt](https://discourse.openehr.org/u/birger.haarbrandt)
#### Post date: [18 June 2026 07:37 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/11 "2026-06-18T07:37:45Z")

</div>

What payload format do you expect the server to provide as a result of the request? And why should we be interested in supporting many flavors of the same kind of requests?

---

<div class="post-metadata">

### Author: ![borut.jures](https://discourse.openehr.org/user_avatar/discourse.openehr.org/borut.jures/32/1391_2.png) [@borut.jures](https://discourse.openehr.org/u/borut.jures)
#### Post date: [18 June 2026 07:50 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/12 "2026-06-18T07:50:05Z")

</div>

Let’s stick to the original question about “having a DV\_CODED\_TEXT constrained to some SNOMED CT ECL query” in archetypes/templates.

I pointed out that I suspect the current use of `terminology://fhir.hl7.org` results from mixing implementation with defining constraints in ADL. I believe the question about payloads is even more implementation-specific.

I prefer to first get answers to the simple questions in my previous post.

---

<div class="post-metadata">

### Author: ![erik.sundvall](https://discourse.openehr.org/user_avatar/discourse.openehr.org/erik.sundvall/32/1961_2.png) [@erik.sundvall](https://discourse.openehr.org/u/erik.sundvall)
#### Post date: [18 June 2026 09:58 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/13 "2026-06-18T09:58:21Z")

</div>

I agree that it would be great to have a clean short/compact way of representing SNOMED-CT expressions in openEHR since Snomed has actually done the job of inventing the nice language ECL. Preferably the URI form for that should come from Snomed International themselves rather than openEHR or FHIR inventing something.

---

<div class="post-metadata">

### Author: ![mikael](https://discourse.openehr.org/user_avatar/discourse.openehr.org/mikael/32/881_2.png) [@mikael](https://discourse.openehr.org/u/mikael)
#### Post date: [12 July 2026 12:53 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/14 "2026-07-12T12:53:46Z")

</div>

My view is that we sooner than later needs to define a standard way to express SNOMED CT Expression Constraint Language ([Expression Constraint Language - Specification and Guide | Specifications SNOMED CT Expression Constraint Language | SNOMED International Documents](https://docs.snomed.org/snomed-ct-specifications/snomed-ct-expression-constraint-language)) within ADL without any additional standard to make it clean and easy. If you prefer to access SNOMED CT by FHIR Terminology Services or any other service should be configured outside the archetypes and templates.

(Short answer due to vacation.)

---

<div class="post-metadata">

### Author: ![yampeku](https://discourse.openehr.org/user_avatar/discourse.openehr.org/yampeku/32/25_2.png) [@yampeku](https://discourse.openehr.org/u/yampeku)
#### Post date: [12 July 2026 13:10 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/15 "2026-07-12T13:10:16Z")

</div>

I general, the most difficult thing about this is that those expressions apply to the full DV\_CODED\_TEXT and not to its individual attributes. Somehow the constraint has to know what part of the response should go in the label, the code (and even the terminology).

This to me screams to a domain type constraint, but I’m 100% against domain types so I won’t propose that ever 😉

---

<div class="post-metadata">

### Author: ![ian.mcnicoll](https://discourse.openehr.org/user_avatar/discourse.openehr.org/ian.mcnicoll/32/4430_2.png) [@ian.mcnicoll](https://discourse.openehr.org/u/ian.mcnicoll)
#### Post date: [12 July 2026 18:55 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/16 "2026-07-12T18:55:33Z")

</div>

Can you explain this further @yampeku

---

<div class="post-metadata">

### Author: ![yampeku](https://discourse.openehr.org/user_avatar/discourse.openehr.org/yampeku/32/25_2.png) [@yampeku](https://discourse.openehr.org/u/yampeku)
#### Post date: [12 July 2026 20:15 UTC](https://discourse.openehr.org/t/how-to-constrain-dv-coded-text-to-a-snomed-ct-ecl-query/17017/17 "2026-07-12T20:15:35Z")

</div>

realistically a constraint with ECL should also mean that the label provided is valid, that the code itself corresponds with a label, etc. and while you can get creative with some vocab operations, e.g. getLabels(ECL), ideally you should only define the ECL once as a constraint on the full data type and not each one of their attributes
