DID.COMMSDOCS

SDK Reference

v1.0.0

Client libraries for JavaScript and Python that wrap the DID.comms v1 REST API. All sovereign proxy rules are enforced — no DID exposure, no client-side keys, no metadata leakage.

Zero DID Exposure

DIDs never leave the proxy. API keys are the only external identifier.

Strip & Seal Always On

Metadata stripping is not toggleable. Every envelope is sealed by default.

No Client-Side Keys

Signing keys are generated and stored by Arcform. SDK never touches raw keys.

Installation

JavaScript / Node.js

npm install @didcomms/sdk
bash

Python

pip install didcomms-sdk
bash

Note: Until the npm/pip packages are published, download the SDK source files above and include them directly in your project.

Quick Setup

JavaScript

import { DIDComms } from "@didcomms/sdk";

const client = new DIDComms({
  apiKey: "ak_your_api_key",       // from /v1/did/activate
  token: "your_session_token",     // from login
  baseUrl: "https://arcform-api.com",
});

// Activate → Send → Check Status
const identity = await client.activate({ label: "My App" });
const receipt  = await client.send("ak_recipient", "Hello sovereign world");
const info     = await client.status();
javascript

Python

from didcomms import DIDComms

client = DIDComms(
    api_key="ak_your_api_key",
    token="your_session_token",
    base_url="https://arcform-api.com",
)

# Activate → Send → Check Status
identity = client.activate(label="My App")
receipt  = client.send("ak_recipient", "Hello sovereign world")
info     = client.status()
python

Authentication Model

The SDK uses a dual-layer auth model. Every request includes:

Authorization— Bearer token from your session (identifies the developer account)
X-DID-API-Key— API key (identifies the sovereign identity performing the action)

Both are set automatically by the SDK constructor. You never need to manage headers manually.

Methods

client.activate(options?)

Create a new sovereign identity and API key. Returns a DID, fingerprint, and API key scoped to the free tier.

Parameters

labelstring— Optional friendly label for the identity

Returns

{ did, fingerprint, api_key_id, plan, usage, metadata_policy, status }

Example

const identity = await client.activate({ label: "Production Key" });
console.log(identity.api_key_id);       // "ak_b1df21..."
console.log(identity.did);              // "did:comms:ff7e..."
console.log(identity.metadata_policy);  // "strip_and_seal"
javascript
client.send(to, message)

Send a sealed envelope to another DID.comms identity. The message is encrypted (X25519-XSalsa20-Poly1305), metadata is stripped and sealed, and the envelope is routed through mediator hops. Raw DIDs are rejected — use API keys only.

Parameters

tostring— Recipient API key (ak_...) — raw DIDs rejected
messagestring— Message content to encrypt and send

Returns

{ envelope_id, envelope_hash, sender, recipient, encryption, routing, metadata_policy, metrics }

Example

const receipt = await client.send("ak_recipient_key", "Hello sovereign world");
console.log(receipt.envelope_id);
console.log(receipt.encryption.status);     // "sealed"
console.log(receipt.routing.hops);          // 2
console.log(receipt.metadata_policy);       // "stripped_and_sealed"
javascript
client.status()

Get the current identity's status, usage counters, plan tier, and registered webhook count.

Returns

{ did, fingerprint, api_key_id, label, status, plan, usage, webhooks, metadata_policy }

Example

const info = await client.status();
console.log(info.usage.messages_remaining);  // 947
console.log(info.usage.utilisation_pct);     // 5
console.log(info.plan);                      // "builder"
javascript
client.verify(envelopeHash)

Verify the delivery status, sender identity, routing integrity, and bubble lifecycle of an envelope. Returns a proof-of-transit object with integrity flags, identity verdict, and signer set resolution. Zero content exposure.

Parameters

envelopeHashstring— The envelope hash to verify

Returns

{ status, envelope_hash, verified_at, proof_checksum, audit_spine, identity, bubble_state, integrity }

Example

const proof = await client.verify("aa4a2d3dadd8ba65");
console.log(proof.status);                            // "verified"
console.log(proof.identity.identity_verdict);         // "ok"
console.log(proof.identity.key_status_at_send);       // "active"
console.log(proof.integrity.proof_checksum_valid);    // true
console.log(proof.bubble_state.signal_type);          // "message"
javascript
client.verifyBatch(envelopeHashes)

Batch-verify multiple envelopes in a single request. Processes in parallel chunks for industrial throughput. Returns individual proofs and an aggregated summary. Maximum 50 hashes per batch.

Parameters

envelopeHashesstring[]— Array of envelope hashes (max 50)

Returns

{ mode, results: Proof[], summary: { total, verified, partial, degraded, orphaned, unverified } }

Example

const batch = await client.verifyBatch([
  "aa4a2d3dadd8ba65",
  "b48f21c316cb75f6"
]);
console.log(batch.summary.verified);   // 2
console.log(batch.summary.degraded);   // 0
batch.results.forEach(p => console.log(p.status));
javascript
client.webhooks.register(url, events?)

Register a webhook endpoint. Sealed envelope deliveries will be pushed to your URL with an HMAC signature in the X-DIDComms-Signature header.

Parameters

urlstring— Your HTTPS endpoint URL
eventsstring[]— Event types (default: ['envelope.received'])

Returns

{ success, webhook_id, url, events, secret, status }

Example

const wh = await client.webhooks.register("https://myapp.com/hooks/didcomms");
// Save the secret for signature verification
console.log(wh.secret);   // "whsec_c904ab..."
console.log(wh.status);   // "active"
javascript
client.webhooks.list()

List all registered webhooks for the current identity, including failure counts and last trigger timestamps.

Returns

{ api_key_id, webhooks: [{ id, url, events, status, failure_count, last_triggered_at }] }

Example

const { webhooks } = await client.webhooks.list();
webhooks.forEach(wh => console.log(wh.url, wh.status));
javascript
client.webhooks.delete(webhookId)

Delete a registered webhook endpoint by ID.

Parameters

webhookIdstring— The webhook record ID to delete

Returns

{ success: true, message }

Example

await client.webhooks.delete("6a3d7ccaaf66...");
javascript
Webhooks.verifySignature(payload, signature, secret)

Static method. Verify an incoming webhook's HMAC-SHA256 signature to confirm it was sent by DID.comms. Use this in your webhook handler before processing the payload.

Parameters

payloadstring— Raw request body string
signaturestring— Value of the X-DIDComms-Signature header
secretstring— Your webhook secret (whsec_...)

Returns

Promise<boolean>

Example

import { Webhooks } from "@didcomms/sdk";

const isValid = await Webhooks.verifySignature(
  rawBody,
  req.headers["x-didcomms-signature"],
  process.env.DIDCOMMS_WEBHOOK_SECRET
);
if (!isValid) return res.status(401).json({ error: "Invalid signature" });
javascript

Error Handling

try {
  const receipt = await client.send("ak_recipient", "Hello");
} catch (err) {
  if (err instanceof DIDCommsError) {
    console.error(err.code);     // "MONTHLY_LIMIT_EXCEEDED"
    console.error(err.status);   // 429
    console.error(err.message);  // "Monthly message limit exceeded."
  }
}
javascript

Error Codes

MISSING_CONFIGapiKey or token not provided to constructor
MISSING_SENDERNo X-DID-API-Key header or api_key_id in body
MISSING_RECIPIENTNo recipient specified in send()
MISSING_PAYLOADNo message content in send()
KEY_NOT_FOUNDAPI key does not exist
KEY_INACTIVEAPI key is revoked or deactivated
RAW_DID_REJECTEDRaw DIDs passed as recipient — use API keys
MONTHLY_LIMIT_EXCEEDEDPlan message quota exhausted

Webhook Verification

Every webhook delivery includes an X-DIDComms-Signature header. Verify it with the static Webhooks.verifySignature() method before processing.

// Express.js webhook handler
app.post("/hooks/didcomms", async (req, res) => {
  const { Webhooks } = require("@didcomms/sdk");
  
  const isValid = await Webhooks.verifySignature(
    JSON.stringify(req.body),
    req.headers["x-didcomms-signature"],
    process.env.DIDCOMMS_WEBHOOK_SECRET
  );
  
  if (!isValid) return res.status(401).json({ error: "Bad signature" });
  
  // Process the sealed envelope event
  const { event, envelope_id, sender } = req.body;
  console.log("Received:", event, "from:", sender);
  
  res.status(200).json({ received: true });
});
javascript