# Domain linking

## Overview

**Domain Linkage** connects a decentralized identifier (**DID**) to a web **origin** using the **Well-Known DID Configuration** standard (DIF / W3C VC). It’s a **two-step flow** that this service automates end-to-end:

1. **Generate (Issue) Domain Linkage** — You request a **Domain Linkage Credential (DLC)** for an HTTPS origin. The service returns a ready-to-host **`did-configuration.json`**. You must publish **exactly that JSON** at:

```
<origin>/.well-known/did-configuration.json
```

2. **Verify Domain Linkage** — You ask the service to verify the published file. The service fetches it, validates that at least one embedded DLC binds **your DID** to **your origin**, and on success **updates your DID Document on-chain** by adding the origin to `alsoKnownAs` and ensuring a canonical `LinkedDomains` service (with `serviceEndpoint.origins`).

**Origin definition (precise):** an HTTPS **origin** is exactly `https://<host>[:<port>]`. It is **only** scheme + host + optional non-443 port. Allowed: `https://example.com`, `https://sub.example.com`, `https://example.com:8443`

***

## Endpoints

### 1) Issue a Domain Linkage Credential

**POST** `/api/v1/domain-linkages`

Creates a **Domain Linkage Credential (DLC)** for the given origin and returns a complete **`did-configuration.json`** to host at your site.

**Request**

```json
{
  "domain": "https://example.com",
  "expirationDays": 90
}
```

* `domain`: HTTPS **origin** only (as defined above).
* `expirationDays`: integer (e.g., 1..10000).

**Response (201)**

```json
{
  "didConfiguration": {
    "@context": "https://identity.foundation/.well-known/did-configuration/v1",
    "linked_dids": [
      { /* Verifiable Credential (includes "DomainLinkageCredential") with JWS proof */ }
    ]
  },
  "publishAt": "https://example.com/.well-known/did-configuration.json",
  "expiresAt": "2026-10-16T10:00:00.000Z"
}
```

**What to publish (important):** Host **only** the JSON inside `didConfiguration` **verbatim** at the `publishAt` URL.

**cURL**

```bash
curl -X POST "https://issuer.example/api/v1/domain-linkages" \
  -H "Authorization: Bearer $CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"domain":"https://example.com","expirationDays":90}'
```

***

### 2) Publish the well-known file

Place the **exact** `didConfiguration` JSON at:

```
https://example.com/.well-known/did-configuration.json
```

If your origin includes a non-default port, publish under that origin (e.g., `https://example.com:8443/.well-known/did-configuration.json`). No extra wrapping, no renaming, no added fields.

***

### 3) Verify & Update DID Document

**POST** `/api/v1/domain-linkages/verify`

Fetches your well-known file, validates at least one embedded DLC against your DID Document, and **updates your DID Document on-chain** to include the origin.

**Request**

```json
{
  "domain": "https://example.com"
}
```

**Response (200)**

```json
{
  "did": "did:empe:xyz...abc"
}
```

**On success (side-effects)**

* Adds the origin to `alsoKnownAs` (de-duplicated).
* Ensures a single canonical service entry:

  ```json
  {
    "id": "did:empe:xyz...abc#linked-domains",
    "type": "LinkedDomains",
    "serviceEndpoint": {
      "origins": ["https://example.com", "..."]
    }
  }
  ```
* Anchors the updated DID Document to the Empe blockchain (version increment). *Note:* Your DID should already be anchored for this update to succeed.

**cURL**

```bash
curl -X POST "https://issuer.example/api/v1/domain-linkages/verify" \
  -H "Authorization: Bearer $CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"domain":"https://example.com"}'
```

***

## The file you publish (`did-configuration.json`) — minimal, correct shape

Publish exactly this **shape** (the “Issue” endpoint fills in the values for you):

```json
{
  "@context": "https://identity.foundation/.well-known/did-configuration/v1",
  "linked_dids": [
    {
      "@context": ["https://www.w3.org/2018/credentials/v1"],
      "type": ["VerifiableCredential", "DomainLinkageCredential"],
      "issuer": { "id": "did:empe:xyz...abc" },
      "issuanceDate": "2025-10-16T10:00:00Z",
      "expirationDate": "2026-10-16T10:00:00Z",
      "credentialSubject": {
        "id": "did:empe:xyz...abc",
        "origin": "https://example.com"
      },
      "proof": {
        "type": "JsonWebSignature2020",
        "verificationMethod": "did:empe:xyz...abc#keys-1",
        "proofPurpose": "assertionMethod",
        "created": "2025-10-16T10:00:00Z",
        "jws": "<compact-jws>"
      }
    }
  ]
}
```

**Notes**

* You may include multiple DLCs in `linked_dids` (e.g., key rotation).
* Different ports mean different origins (`https://example.com` vs `https://example.com:8443`) and must be issued, published, and verified separately.


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.empe.io/develop/issuer/domain-linkage.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
