Skip to navigation

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

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)

{
"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

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

Response (200 OK)

{
"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

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

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

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

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

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

Response (200 OK)

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

Key Rotation

Rotates a cryptographic key in the DID Document.

Request

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)

{
"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

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.

Challenge Request

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

Challenge Response

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

Signing the Challenge

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

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

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