Rights Layer Specification

Example API Draft

Status: Draft v0.1.0 — This section is informative. It is explicitly non-normative and illustrative.

This document sketches how a system could expose Rights Layer expressions through a resource-oriented interface. It exists only to make the Data Model tangible.

This draft imposes no requirements. Any protocol may be used — or none. Conformance to Rights Layer is defined only over expressions (Data Model, section 5), never over APIs. A system that exchanges conforming expressions by file transfer, message queue, removable media, or paper is exactly as conformant as one that implements every operation below. No specific protocol, transport, serialization framework, or product is assumed or required (Principle P1 in Core Principles).

The interface is also purely descriptive, like the layer itself (Principle P7): the operations below record and retrieve expressions. Whether a caller is authenticated, whether a request is authorized, and whether a Decision is enforced are matters for the deployment, addressed by mechanisms of its choice (an authentication mechanism, an authorization mechanism, transport security — see Security Considerations).

1. Abstract Operations

The operations are defined protocol-neutrally. Each takes and returns entities of the Data Model; “returns” means returning a Rights Layer expression (or fragment) containing the named entities.

1.1 GetRight(id)

1.2 ListRightsBySubject(subjectRef)

1.3 GetEvents(aboutRef, since)

1.4 RequestExercise(rightRef, actionRef)

1.5 SubmitEligibilityResponse(eligibilityRef, response)

1.6 GetDecision(requestRef)

1.7 RecordExerciseEvent(exerciseRef, eventType, occurredAt, actorRef, data, proof)

2. An Illustrative HTTP+JSON Mapping

One possible mapping — again, illustrative only — onto plain HTTP with the canonical JSON serialization:

Abstract operation HTTP mapping
GetRight(id) GET /rights/{id}
ListRightsBySubject(subjectRef) GET /rights?subject={subjectRef}
GetEvents(aboutRef, since) GET /events?about={aboutRef}&since={timestamp}
RequestExercise(rightRef, actionRef) POST /exercise-requests
SubmitEligibilityResponse(eligibilityRef, response) POST /eligibilities/{id}/response
GetDecision(requestRef) GET /decisions?request={requestRef}
RecordExerciseEvent(…) POST /exercises/{id}/events

Identifiers are URIs and would be URL-encoded where they appear in paths or query strings. Error handling, pagination, content negotiation, versioning, and transport security are deliberately unspecified here — a real deployment would define them with mechanisms of its choice.

2.1 Example: requesting an exercise

Using the data of the driving licence example: Alice requests to exercise the drive Action of her driving licence Right.

Request:

POST /exercise-requests
Content-Type: application/json

{
  "rightRef": "urn:example:right:alice-driving-licence",
  "actionRef": "urn:example:action:drive-ordinary"
}

Response — the recorded ExerciseRequested Event:

HTTP/1.1 201 Created

{
  "@context": "https://rights-layer.org/ns/v0",
  "type": "RightsExpression",
  "specVersion": "0.1.0",
  "entities": [
    {
      "id": "urn:example:event:exercise-request-1",
      "type": ["Event", "ExerciseEvent"],
      "eventType": "ExerciseRequested",
      "aboutRef": "urn:example:exercise:drive-2026-07-01",
      "actorRef": "urn:example:subject:alice",
      "occurredAt": "2026-07-01T07:59:00+09:00"
    }
  ]
}

2.2 Example: submitting an Eligibility Response

The licensing authority — a Response issuer, entirely outside the layer — has evaluated the requirement of the Eligibility urn:example:eligibility:licence-valid and presents its Boolean answer:

POST /eligibilities/urn%3Aexample%3Aeligibility%3Alicence-valid/response
Content-Type: application/json

{
  "id": "urn:example:response:licence-valid-2026-07-01",
  "type": "EligibilityResponse",
  "value": true,
  "issuerRef": "urn:example:authority:public-safety-commission",
  "issuedAt": "2026-07-01T08:00:00+09:00",
  "proof": {
    "type": "ProofReference",
    "proofKind": "registry-lookup",
    "reference": "urn:example:licence-register:attestation:7c1"
  },
  "evidenceRefs": ["urn:example:evidence:licence-record-check"]
}

Response — the recorded EligibilityResponseIssued Event:

HTTP/1.1 201 Created

{
  "@context": "https://rights-layer.org/ns/v0",
  "type": "RightsExpression",
  "specVersion": "0.1.0",
  "entities": [
    {
      "id": "urn:example:event:response-issued-1",
      "type": "Event",
      "eventType": "EligibilityResponseIssued",
      "aboutRef": "urn:example:eligibility:licence-valid",
      "actorRef": "urn:example:authority:public-safety-commission",
      "occurredAt": "2026-07-01T08:00:00+09:00",
      "data": { "responseRef": "urn:example:response:licence-valid-2026-07-01", "value": true }
    }
  ]
}

The second Eligibility of the Action (urn:example:eligibility:conditions-met) receives its own Response from its own issuer in the same way. Each Response answers exactly one Eligibility.

2.3 Example: retrieving the decision

Request:

GET /decisions?request=urn%3Aexample%3Aevent%3Aexercise-request-1

Response — both Eligibilities of the Action have exactly one verifiable Response and both are true, so a Decision was established:

HTTP/1.1 200 OK

{
  "@context": "https://rights-layer.org/ns/v0",
  "type": "RightsExpression",
  "specVersion": "0.1.0",
  "entities": [
    {
      "id": "urn:example:decision:drive-2026-07-01",
      "type": "Decision",
      "actionRef": "urn:example:action:drive-ordinary",
      "rightRef": "urn:example:right:alice-driving-licence",
      "responseRefs": [
        "urn:example:response:licence-valid-2026-07-01",
        "urn:example:response:conditions-met-2026-07-01"
      ],
      "requestRef": "urn:example:event:exercise-request-1",
      "establishedAt": "2026-07-01T08:00:01+09:00"
    }
  ]
}

If any Eligibility were unanswered, or any Response were false, no Decision would exist and this request would return nothing (for example, an empty expression or a not-found status — the deployment’s choice). Absence of a Decision means only that it is not established; there is no negative Decision to retrieve.

A consumer that wants more than the claim follows the Decision’s responseRefs to each Eligibility Response, each Response’s proof to the issuer’s verification mechanism, and each Response’s evidenceRefs to the Evidence, its evidenceSourceRef to the Evidence Source, and its Proof Reference to the verification mechanism the governing system provides (see Architecture, section 3, and Security Considerations).

3. Status of This Sketch

To restate: nothing in this document is required. It is one way, among arbitrarily many, to expose expressions. Deployments may expose fewer operations, more operations, different operations, or no operations at all. The only conformance target in Rights Layer v0.1.0 is the expression itself.