> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.adid.dev/llms.txt.
> For full documentation content, see https://docs.adid.dev/llms-full.txt.

# DID Operations

This document details all CRUD operations available for `did:adi` identifiers, including request/response formats, authentication requirements, and error handling.

## Operation Summary

| Operation           | Method | Endpoint                         | Auth Required |
| ------------------- | ------ | -------------------------------- | ------------- |
| Create DID          | POST   | `/api/v1/dids`                   | API Key       |
| Resolve DID         | GET    | `/api/v1/dids/{did}`             | None          |
| Update DID Document | PATCH  | `/api/v1/dids/{did}`             | DID Auth      |
| Deactivate DID      | DELETE | `/api/v1/dids/{did}`             | DID Auth      |
| Rotate Key          | POST   | `/api/v1/dids/{did}/keys/rotate` | DID Auth      |
| Recover DID         | POST   | `/api/v1/dids/{did}/recover`     | Recovery Key  |
| List DID History    | GET    | `/api/v1/dids/{did}/history`     | None          |

## Create DID

Creates a new DID on the ADI blockchain with an associated DID Document.

### Request

```http
POST /api/v1/dids
Content-Type: application/json
Authorization: Bearer <api-key>

{
  "method": "adi",
  "keyType": "Ed25519",
  "options": {
    "additionalKeys": [
      { "type": "X25519KeyAgreementKey2020", "purpose": ["keyAgreement"] },
      { "type": "Bls12381G2Key2020", "purpose": ["assertionMethod"] }
    ],
    "serviceEndpoints": [
      {
        "type": "DIDCommMessaging",
        "serviceEndpoint": "https://agent.example.com/didcomm"
      }
    ],
    "recoveryKey": true
  }
}
```

### Response (201 Created)

```json
{
  "did": "did:adi:3f7a9b2e1c4d5f6a8b0c2d4e6f8a0b2c...",
  "didDocument": { "..." },
  "keys": {
    "authentication": {
      "keyId": "did:adi:3f7a...#key-1",
      "publicKey": "z6Mkf5rGMoatrSj1f...",
      "privateKey": "** STORE SECURELY **"
    },
    "keyAgreement": {
      "keyId": "did:adi:3f7a...#key-agreement-1",
      "publicKey": "z6LShs9GGnqk85JBB...",
      "privateKey": "** STORE SECURELY **"
    },
    "recovery": {
      "keyId": "did:adi:3f7a...#recovery-1",
      "publicKey": "z6Mkw8PVjR5rGMoat...",
      "privateKey": "** STORE SECURELY - OFFLINE **"
    }
  },
  "transactionHash": "0x7f3a...e2b1",
  "blockNumber": 12345
}
```

## Resolve DID

Resolves a DID to its DID Document and metadata. No authentication required.

### Request

```http
GET /api/v1/dids/did:adi:3f7a9b2e1c4d5f6a8b0c2d4e6f8a0b2c...
Accept: application/did+ld+json
```

### Response (200 OK)

```json
{
  "didDocument": {
    "@context": ["https://www.w3.org/ns/did/v1", "..."],
    "id": "did:adi:3f7a9b2e1c4d...",
    "..."
  },
  "didDocumentMetadata": {
    "created": "2026-03-28T10:00:00Z",
    "updated": "2026-03-28T10:00:00Z",
    "versionId": 1,
    "deactivated": false
  },
  "didResolutionMetadata": {
    "contentType": "application/did+ld+json",
    "duration": 42
  }
}
```

### Resolution with Version

```http
GET /api/v1/dids/did:adi:3f7a...?versionId=2
GET /api/v1/dids/did:adi:3f7a...?versionTime=2026-03-28T10:00:00Z
```

## Update DID Document

Updates the DID Document. Requires DID Auth (signature from a current authentication key).

### Add a Service Endpoint

```http
PATCH /api/v1/dids/did:adi:3f7a...
Content-Type: application/json
Authorization: DIDAuth <signed-challenge>

{
  "operation": "addService",
  "service": {
    "id": "#agent-card",
    "type": "AgentCard",
    "serviceEndpoint": "https://agent.example.com/.well-known/agent.json"
  }
}
```

### Add a Verification Method

```http
PATCH /api/v1/dids/did:adi:3f7a...
Content-Type: application/json
Authorization: DIDAuth <signed-challenge>

{
  "operation": "addVerificationMethod",
  "verificationMethod": {
    "type": "EcdsaSecp256k1VerificationKey2019",
    "publicKeyMultibase": "zQ3shokFTS3brHcDQrn82..."
  },
  "relationships": ["authentication"]
}
```

### Remove a Verification Method

```http
PATCH /api/v1/dids/did:adi:3f7a...
Content-Type: application/json
Authorization: DIDAuth <signed-challenge>

{
  "operation": "removeVerificationMethod",
  "keyId": "did:adi:3f7a...#key-2"
}
```

> Note: The last authentication key cannot be removed. Use key rotation instead.

## Deactivate DID

Permanently deactivates a DID. This is irreversible.

### Request

```http
DELETE /api/v1/dids/did:adi:3f7a...
Authorization: DIDAuth <signed-challenge>

{
  "confirm": true,
  "reason": "gdpr-erasure"
}
```

### Response (200 OK)

```json
{
  "did": "did:adi:3f7a...",
  "deactivated": true,
  "transactionHash": "0x9d4e...f1a2",
  "blockNumber": 12500
}
```

## Key Rotation

Rotates a cryptographic key in the DID Document.

### Request

```http
POST /api/v1/dids/did:adi:3f7a.../keys/rotate
Authorization: DIDAuth <signed-challenge>

{
  "oldKeyId": "did:adi:3f7a...#key-1",
  "newKeyType": "Ed25519VerificationKey2020",
  "purpose": ["authentication", "assertionMethod"],
  "revokeOldAfter": "2026-04-28T00:00:00Z"
}
```

### Response (200 OK)

```json
{
  "newKey": {
    "keyId": "did:adi:3f7a...#key-3",
    "publicKey": "z6MkpTHR8VNs73oMz...",
    "privateKey": "** STORE SECURELY **"
  },
  "gracePeriodEnd": "2026-04-28T00:00:00Z",
  "transactionHash": "0xab12...cd34"
}
```

## DID Recovery

Recovers a DID when authentication keys are lost.

### Request

```http
POST /api/v1/dids/did:adi:3f7a.../recover
Authorization: RecoveryKey <signed-challenge>

{
  "newAuthenticationKey": {
    "type": "Ed25519VerificationKey2020",
    "publicKeyMultibase": "z6MknewKey123..."
  },
  "revokeAllExistingKeys": true
}
```

## DID Auth (Challenge-Response)

DID Auth is the authentication mechanism for operations requiring proof of DID control.

```mermaid
sequenceDiagram
    participant Client
    participant IDA API

    Client->>IDA API: GET /auth/challenge?did=did:adi:3f7a...
    IDA API->>Client: { challenge: "random-nonce-xyz", expiresAt: "..." }

    Client->>Client: Sign challenge with authentication private key
    Client->>IDA API: Authorization: DIDAuth base64(did + "." + signature)
    IDA API->>IDA API: Resolve DID, verify signature against auth key
    IDA API->>Client: Authenticated request proceeds
```

### Challenge Request

```http
GET /auth/challenge?did=did:adi:3f7a...
```

### Challenge Response

```json
{
  "challenge": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "did": "did:adi:3f7a...",
  "expiresAt": "2026-03-28T10:05:00Z"
}
```

### Signing the Challenge

```javascript
import { sign } from '@stablelib/ed25519';

const challenge = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
const signature = sign(privateKey, new TextEncoder().encode(challenge));
const authHeader = `DIDAuth ${btoa(did + '.' + base64url(signature))}`;
```

## Error Responses

| Status | Code               | Description                          |
| ------ | ------------------ | ------------------------------------ |
| 400    | `INVALID_DID`      | DID format is invalid                |
| 401    | `AUTH_REQUIRED`    | DID Auth required but not provided   |
| 401    | `AUTH_FAILED`      | Signature verification failed        |
| 404    | `DID_NOT_FOUND`    | DID does not exist on ADI blockchain |
| 409    | `DID_EXISTS`       | DID already registered               |
| 410    | `DID_DEACTIVATED`  | DID has been deactivated             |
| 422    | `INVALID_DOCUMENT` | DID Document validation failed       |
| 429    | `RATE_LIMITED`     | Too many requests                    |
| 500    | `BLOCKCHAIN_ERROR` | ADI blockchain transaction failed    |

### Error Response Format

```json
{
  "error": {
    "code": "DID_NOT_FOUND",
    "message": "DID did:adi:3f7a... not found on ADI blockchain",
    "details": {
      "did": "did:adi:3f7a..."
    }
  }
}
```