DID Operations

View as Markdown

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

Operation Summary

OperationMethodEndpointAuth Required
Create DIDPOST/api/v1/didsAPI Key
Resolve DIDGET/api/v1/dids/{did}None
Update DID DocumentPATCH/api/v1/dids/{did}DID Auth
Deactivate DIDDELETE/api/v1/dids/{did}DID Auth
Rotate KeyPOST/api/v1/dids/{did}/keys/rotateDID Auth
Recover DIDPOST/api/v1/dids/{did}/recoverRecovery Key
List DID HistoryGET/api/v1/dids/{did}/historyNone

Create DID

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

Request

1POST /api/v1/dids
2Content-Type: application/json
3Authorization: Bearer <api-key>
4
5{
6 "method": "adi",
7 "keyType": "Ed25519",
8 "options": {
9 "additionalKeys": [
10 { "type": "X25519KeyAgreementKey2020", "purpose": ["keyAgreement"] },
11 { "type": "Bls12381G2Key2020", "purpose": ["assertionMethod"] }
12 ],
13 "serviceEndpoints": [
14 {
15 "type": "DIDCommMessaging",
16 "serviceEndpoint": "https://agent.example.com/didcomm"
17 }
18 ],
19 "recoveryKey": true
20 }
21}

Response (201 Created)

1{
2 "did": "did:adi:3f7a9b2e1c4d5f6a8b0c2d4e6f8a0b2c...",
3 "didDocument": { "..." },
4 "keys": {
5 "authentication": {
6 "keyId": "did:adi:3f7a...#key-1",
7 "publicKey": "z6Mkf5rGMoatrSj1f...",
8 "privateKey": "** STORE SECURELY **"
9 },
10 "keyAgreement": {
11 "keyId": "did:adi:3f7a...#key-agreement-1",
12 "publicKey": "z6LShs9GGnqk85JBB...",
13 "privateKey": "** STORE SECURELY **"
14 },
15 "recovery": {
16 "keyId": "did:adi:3f7a...#recovery-1",
17 "publicKey": "z6Mkw8PVjR5rGMoat...",
18 "privateKey": "** STORE SECURELY - OFFLINE **"
19 }
20 },
21 "transactionHash": "0x7f3a...e2b1",
22 "blockNumber": 12345
23}

Resolve DID

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

Request

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

Response (200 OK)

1{
2 "didDocument": {
3 "@context": ["https://www.w3.org/ns/did/v1", "..."],
4 "id": "did:adi:3f7a9b2e1c4d...",
5 "..."
6 },
7 "didDocumentMetadata": {
8 "created": "2026-03-28T10:00:00Z",
9 "updated": "2026-03-28T10:00:00Z",
10 "versionId": 1,
11 "deactivated": false
12 },
13 "didResolutionMetadata": {
14 "contentType": "application/did+ld+json",
15 "duration": 42
16 }
17}

Resolution with Version

1GET /api/v1/dids/did:adi:3f7a...?versionId=2
2GET /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

1PATCH /api/v1/dids/did:adi:3f7a...
2Content-Type: application/json
3Authorization: DIDAuth <signed-challenge>
4
5{
6 "operation": "addService",
7 "service": {
8 "id": "#agent-card",
9 "type": "AgentCard",
10 "serviceEndpoint": "https://agent.example.com/.well-known/agent.json"
11 }
12}

Add a Verification Method

1PATCH /api/v1/dids/did:adi:3f7a...
2Content-Type: application/json
3Authorization: DIDAuth <signed-challenge>
4
5{
6 "operation": "addVerificationMethod",
7 "verificationMethod": {
8 "type": "EcdsaSecp256k1VerificationKey2019",
9 "publicKeyMultibase": "zQ3shokFTS3brHcDQrn82..."
10 },
11 "relationships": ["authentication"]
12}

Remove a Verification Method

1PATCH /api/v1/dids/did:adi:3f7a...
2Content-Type: application/json
3Authorization: DIDAuth <signed-challenge>
4
5{
6 "operation": "removeVerificationMethod",
7 "keyId": "did:adi:3f7a...#key-2"
8}

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

Deactivate DID

Permanently deactivates a DID. This is irreversible.

Request

1DELETE /api/v1/dids/did:adi:3f7a...
2Authorization: DIDAuth <signed-challenge>
3
4{
5 "confirm": true,
6 "reason": "gdpr-erasure"
7}

Response (200 OK)

1{
2 "did": "did:adi:3f7a...",
3 "deactivated": true,
4 "transactionHash": "0x9d4e...f1a2",
5 "blockNumber": 12500
6}

Key Rotation

Rotates a cryptographic key in the DID Document.

Request

1POST /api/v1/dids/did:adi:3f7a.../keys/rotate
2Authorization: DIDAuth <signed-challenge>
3
4{
5 "oldKeyId": "did:adi:3f7a...#key-1",
6 "newKeyType": "Ed25519VerificationKey2020",
7 "purpose": ["authentication", "assertionMethod"],
8 "revokeOldAfter": "2026-04-28T00:00:00Z"
9}

Response (200 OK)

1{
2 "newKey": {
3 "keyId": "did:adi:3f7a...#key-3",
4 "publicKey": "z6MkpTHR8VNs73oMz...",
5 "privateKey": "** STORE SECURELY **"
6 },
7 "gracePeriodEnd": "2026-04-28T00:00:00Z",
8 "transactionHash": "0xab12...cd34"
9}

DID Recovery

Recovers a DID when authentication keys are lost.

Request

1POST /api/v1/dids/did:adi:3f7a.../recover
2Authorization: RecoveryKey <signed-challenge>
3
4{
5 "newAuthenticationKey": {
6 "type": "Ed25519VerificationKey2020",
7 "publicKeyMultibase": "z6MknewKey123..."
8 },
9 "revokeAllExistingKeys": true
10}

DID Auth (Challenge-Response)

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

Challenge Request

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

Challenge Response

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

Signing the Challenge

1import { sign } from '@stablelib/ed25519';
2
3const challenge = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
4const signature = sign(privateKey, new TextEncoder().encode(challenge));
5const authHeader = `DIDAuth ${btoa(did + '.' + base64url(signature))}`;

Error Responses

StatusCodeDescription
400INVALID_DIDDID format is invalid
401AUTH_REQUIREDDID Auth required but not provided
401AUTH_FAILEDSignature verification failed
404DID_NOT_FOUNDDID does not exist on ADI blockchain
409DID_EXISTSDID already registered
410DID_DEACTIVATEDDID has been deactivated
422INVALID_DOCUMENTDID Document validation failed
429RATE_LIMITEDToo many requests
500BLOCKCHAIN_ERRORADI blockchain transaction failed

Error Response Format

1{
2 "error": {
3 "code": "DID_NOT_FOUND",
4 "message": "DID did:adi:3f7a... not found on ADI blockchain",
5 "details": {
6 "did": "did:adi:3f7a..."
7 }
8 }
9}