Back to the resolver.

lid: URI scheme (version 1.0)

A lid: URI has the following structure:

lid: [ // host / ] ( [ ' ] name / )* [ $ ] value [ @ type ] [ ? context ] [ # fragment ]
The hostname of the server storing the target dataset. The server is queried, usually with the HTTP or HTTPS protocol, for the entity represented by the remainder of the URI.
A URI name, as an absolute URI reference or a prefix (may be empty) and a local name, separated with :.
the compared value of the property chain. If preceded by the $, it is treated as a name and expanded accordingly. May be empty.
Specifies the type of the literal value. Could be a language code, a language range, a name, or empty. If it is omitted altogether, the literal is simply compared by its string value, without a type comparison. A valid language code or language range with an additional hyphen (-) at the end is always interpreted as a language range stripped of it. Special names listed below are not applicable here, as they already match a language code.
Additional key-value pairs. If the key starts on _, it is a resolver-specific option, otherwise it is a prefix (re)definition (without the :) and the value is treated as a name. The prefixes are processed in order, that is the second prefix definition uses the context created by the first prefix definition, and so on. Assigning an empty literal value to a prefix name undefines the prefix.
Used to find the target entity within the resource specified by the URI by the navigator. If the location of the resource already contains a fragment, it is replaced.

All special characters may be escaped with % per standard URI rules to be interpreted literally, without a special meaning. Inside a name, characters !, &, (, ), *, +, ,, and ; are reserved for future possible use and must be percent-encoded.

The path portion of the URI consists of a property path, followed by an identifier. Each property corresponds to a step in the corresponding property chain with the identifier at its end and the identified entity at its beginning. ' before a property represents its inverse. The initial node in the property path is considered the queried entity, while the final node is the identifier (final component of the URI path).

When a name is expected, a special identifier may be used instead, which doesn't match its usual structure. These are:

This is synonymous to the URI with no additional meaning.
This links a URI node to its actual literal representation (as an xsd:anyURI), and has to be used when looking for an entity by its URI, as only literal nodes are compared with the value. Blank nodes and literal nodes do not have this property. When this property is to be materialized, it is represented by, but it is not synonymous with it in any other case.

Every occurence of a name with a prefix is interpreted according to the defined prefixes in the current context. Definitions in the query portion are processed first and they specify the context for the path.

There are several prefixes defined initially. They are divided into three categories:

Common prefixes
PREFIX rdf: <>
PREFIX rdfs: <>
PREFIX owl: <>
PREFIX skos: <>
PREFIX xsd: <>

These prefixes are always available and commonly used in the constructed queries. Redefining them will only affect their specific usage in the URI, not their generated usage in the query.

Common URI schemes
PREFIX http: <http:>
PREFIX https: <https:>
PREFIX urn: <urn:>
PREFIX tag: <tag:>
PREFIX mailto: <mailto:>
PREFIX data: <data:>
PREFIX file: <file:>
PREFIX ftp: <ftp:>

These prefixes are defined in order to make it possible to write : instead of %3A in a name without relying on the target endpoint to support these prefixes.

Supplemental prefixes
PREFIX base: <>

Relative URIs are not allowed by the syntax, thus they have to be represented via base:. . and .. are not handled in any special manner.

This prefix would make it possible to express an absolute URI, like in base:urn:something. Producing absolute URIs this way is therefore explicitly disallowed: a prefix that denotes a relative URI cannot be used to produce an absolute URI (the converse is already true by definition for absolute URIs).

The empty prefix is always undefined initially, as well as any prefix that starts on x.. Any undefined prefix may still be used in any name, but it is up to the resolver or target to interpret it.

In addition to the prefixes declared above, a particular resolver may define additional prefixes. It is recommended to include the RDFa Core Initial Context in this set to simplify using other common prefixes, and to consider defining other URI schemes to eliminate the confusion with prefixes.

Examples of valid syntax

All of the URIs below are valid, with or without a host portion (// after lid:).

The path may be omitted completely, in which case the URI refers to any empty literal value.
This refers to the literal value "1"^^xsd:integer itself.
This refers to the literal value "1", which is treated as a plain untagged literal in RDF 1.0 and an xsd:string-typed literal in RDF 1.1, which may be considered distinct entities by the target.
This refers to the string example in the English language (no dialect).
This refers to any string example in any dialect of the English language.
This refers to any string example in English without any conditions regarding the dialect.
This refers to the literal (with any datatype).
This refers to the entity identified by the URI
Likewise ‒ the URI is considered to have the datatype xsd:anyURI, so both options work.
This does not represent any meaningful entity, since the URI cannot have any other type than xsd:anyURI.
This refers to the entity identified by the URI The mailto: part is not treated as a prefix here (the first two cases are not a name, the last one does not have a prefix, so there is no point to $).
This refers to same entity, but the mailto: part is treated as an actual prefix (defined as itself), and so other vocabulary prefixes may be used in its place.
This refers to any entity that is defined by the FOAF vocabulary.
This refers to an entity that has a textual label (as xsd:anyURI) which can be interpreted as the URI of an entity with value x.


A lid: URI on its own usually refers to entities described by a particular dataset. The purpose of creating such a URI is to produce a persistent identifier when one is unavailable (such as for a blank node) which is easy to read and interpret, and serves as a link into the dataset.

lid: URIs do not have a single possible resolution mechanism, but they are designed for use with SPARQL endpoints (located at /sparql under a particular host) and a particular resolver may use parts of the URI to construct a SPARQL query which retrieves the identified resource, in some form specific to the resolver.

The basic translation to a SPARQL query is simple and only uses a single property path, coupled with a check on the identifier. More advanced resolvers, such as the one hosted here, may however offer additional features, for example basic inference from subproperties, or unification based on standard properties like owl:sameAs, in which case the query may become more complex, while still resembling the simple one.

The SPARQL query generated by a resolver should generally be valid, but there is one exception: unbound prefixes may be used. These are not part of the standard SPARQL syntax, but they are commonly understood by SPARQL endpoint implementations. Using an unbound prefix means using whichever namespace is understood by the endpoint for that prefix, if some at all.

As an example, the simple URI lid:foaf:nick/John could be translated to a SPARQL query as follows:

PREFIX foaf: <> # Assuming the resolver understands the prefix.

DESCRIBE ?subject # Other clauses are possible, depending on the access method.
  ?subject foaf:nick ?id .
  FILTER (isLITERAL(?id) && STR(?id) = "John") # Since datatype is not given, the value has to be compared.

The FILTER clause can be avoided if the datatype is specified:

# lid:foaf:nick/John@
?subject foaf:nick "John" .
# lid:foaf:nick/John@en
?subject foaf:nick "John"@en .

But not if a language range is required:

# lid:foaf:nick/John@en- ?subject foaf:nick ?id . FILTER (isLITERAL(?id) && LANGMATCHES(lang(?id), "en") && STR(?id) = "John")

It is also possible to automatically use metadata in the query, such as by looking for any sub-property of foaf:nick:

PREFIX rdfs: <>

DESCRIBE ?subject
  ?nick rdfs:subPropertyOf* <> .
  ?subject ?nick "John" .

This query will accept any predicate using the property foaf:nick, but also any sub-property of it.

The particular handling of prefixes not in those mentioned in the specification is resolver-defined, so if the resolver is not aware of foaf:, the query might behave similarly as when the prefix is undefined:

# lid:foaf:nick/John@?foaf=
DESCRIBE ?subject
  ?subject foaf:nick "John" .

This is invalid, but commonly understood SPARQL, leaving the definition of foaf: for the target triple store.

A resolver may also decide to define the prefix through metadata, such as by:

# lid:foaf:nick/John@?foaf=
PREFIX rdfa: <>

DESCRIBE ?subject
  "foaf" ^rdfa:prefix/rdfa:uri ?foaf .
  FILTER isLiteral(?foaf)
  BIND (URI(CONCAT(STR(?foaf), "nick")) AS ?nick)
  ?subject ?nick "John" .


A lid: URI can be constructed to point to specific resources which can be thought of as synonymous under the RDF semantics. Here are some examples of possible entailment that may arise automatically from the use of a lid: URI.

<lid:example@en> owl:sameAs "example"@en . # A property-less lid: URI is a way to identify a literal value.
<lid:uri/urn:something> owl:sameAs <urn:something> . # A way to encode a normal URI if needed, or to shorten it via a known prefix.
<lid:15> skos:narrower "15", 15, "15"^^xsd:double . # The concept of a literal value with unspecified type is broader than any of the concrete literals.
<lid:hello@en-*> skos:narrower "hello"@en-us, "hello"@en-gb . # Likewise for language ranges.

Additionally, the presence of a hostname in the URI might change its meaning in these ways:

Encoding considerations

Every variable portion of the URI is eventually percent-decoded exactly once, even absolute URIs stored as a name, including encoded UTF-8 characters. International characters (valid in IRI but not URI) are left unchanged. If a name is supposed to resolve to a URI with percent-encoded characters, the percent itself must be escaped in the lid: URI.

Interoperability considerations

A particular lid: URI may contain undefined prefixes whose resolution depends on the resolver or target, and if those prefixes are not defined explicitly in the URI, it may resolve to different entities even within otherwise equal graphs. It is however possible to define such prefixes explicitly.

Another point of difference are resolver-specific options, whose interpretation is defined solely by the resolver and may affect which entities are identified by a particular lid: URI and which are not.

Security considerations

As lid: URIs may contain arbitrary identifiers, applications should not expose such URIs beyond the intended restrictions of used confidential or private identifiers. Additionally, while lid: URIs do not define a particular navigation mechanism, individual resolvers may choose redirecting to a URI identifying the resolved resource as an option. If such is the case, the same security precautions as when navigating to an arbitrary URI should be taken.