Skip to main content
This guide begins with a read-only request. It then creates an OpenPayload identity entirely on your machine and finishes by sending a minimal live message through a Relay. For OpenPayload-operated services, use the public alpha endpoints. The examples below keep placeholder hostnames so you can also follow this guide with another operator.

Choose your starting point

Read a public DID first

A terminal is the text-based application where you type commands. On macOS it is named Terminal. On Windows you can use PowerShell. On Linux it may be named Terminal, Console, or Shell. Ask your Directory operator for:
  • Its HTTPS base URL
  • A confirmed public OpenPayload DID you may use for testing
Then run:
Replace both placeholders. This request is read-only. It does not create an identity, spend funds, or modify network state. If you receive JSON containing document, aliases, devices, and registration_status, your connection is working. A 404 means the sample DID is not registered on that Directory; it does not necessarily mean your command is malformed.

Create an identity locally

The remaining steps generate an Ed25519 keypair, build a public DID document, and sign a registration payload. A public key may be shared. A private key proves control of the identity and must remain secret.
POST /register-did creates an ownerless DID using the root-key registration proof. Later Directory updates use the root or another authorized DID key; they do not require a chain account.
Your private key controls the identity. Never print it, commit it, include it in a request, or send it to the Directory.

Prerequisites

Choose either the Bash or Python workflow.
Install the following command-line tools:
  • Bash or another POSIX-compatible shell
  • OpenSSL 3 with Ed25519 support
  • Python 3 for Base58 encoding using only the standard library
  • jq for constructing JSON
  • curl for submitting the request
Confirm that OpenSSL exposes Ed25519:
If this command returns no match, install or select OpenSSL 3 before continuing. The LibreSSL version bundled with some operating systems may not support the commands in this guide.

Set the Directory URL

Replace the placeholder with the HTTPS URL supplied by your Directory operator:
The generation steps do not contact the Directory. You use this URL only when you submit or resolve the DID.

Generate the identity

Create generate-openpayload-identity.sh with the following content:
Make the script executable and run it:

Review the generated files

This quickstart creates a minimal identity with empty keyAgreement and service arrays. That identity can be registered, but it does not yet advertise an encryption key, Relay, or Cache. Before using it for messaging, publish the components shown in A complete messaging DID document.
Both workflows create the same artifacts:
Inspect the DID document and registration body before submission:
Confirm that these values agree:
  • registration.json.did equals did_document.id.
  • The first verificationMethod.id starts with the same DID.
  • controller equals the DID.
  • root_pubkey equals the first publicKeyMultibase value.
  • registration.json does not contain the private key.

Register the DID

Submit the generated request:
A successful submission returns 202 Accepted with a transaction identifier and a pending registration status:
202 Accepted means the Directory accepted the registration for processing. It does not mean the registration is confirmed.

Wait for confirmation

Read the DID from the registration file and URL-encode it for the path:
Check the registration state:
The response reports one of these states: A 502 response means the Directory could not verify chain state. Retry the status request; do not interpret it as missing.

Resolve the DID

Resolve the public record:
If resolution returns 425 with recipient_registration_pending, check registration status again. A confirmed record returns 200 and includes:

Send a live Relay message

You can now use the confirmed DID as both the sender’s test destination and the WebSocket recipient. This keeps the first message focused on the live Relay path:
  1. The recipient opens a WebSocket session with the Relay.
  2. You compose a minimal Hello World! envelope.
  3. You submit the envelope to POST /relay.
  4. The Relay delivers it to the connected WebSocket.
WebSocket is the live receiving path in this example. Envelope submission uses POST /relay; the Relay does not accept outbound envelopes as WebSocket frames.

Set the Relay URLs

Ask your Relay operator for its HTTPS and WebSocket base URLs, then set both values:
This example does not configure or call a Cache service. Keep the recipient WebSocket connected while you submit the message.

Open the recipient WebSocket

Open a second terminal and connect the DID you registered above. The device identifier hello-world is local to this live session. This command uses npx, which is included with Node.js. You can use another WebSocket client if you prefer.
The Relay sends a welcome frame after the connection opens:
Leave this terminal open.

Compose the smallest test envelope

Return to your first terminal. Generate a new message identifier and current timestamp, then write the envelope:
The resulting envelope contains only the fields needed for this live transport smoke test:
This intentionally readable payload is only for a public, non-sensitive smoke test. Base64 encoding is not encryption. Encrypt the payload and protected context before sending real data; continue with Build a DDN message envelope for that flow.

Submit the message

Send the envelope to the Relay:
A successful live delivery reports the WebSocket mode and confirms that no Cache fallback was attempted:
Your WebSocket terminal receives the same DDN envelope, including:
If the Relay does not return local_websocket, confirm that the WebSocket is still connected under the same DID and that the DID registration is finalized.

Protect the private key

After registration:
  1. Move private-key.pem into your secret manager or encrypted key store.
  2. Keep at least one secure recovery copy.
  3. Do not commit the generated directory to source control.
  4. Delete unneeded binary intermediates after you confirm your backup and signing workflow.
Add the generated directory to .gitignore:

Explore the Directory API

Continue with alias, device, DID document, and delivery policy endpoints.