curl --request PUT \
--url "https://directory.example.com/personas/example.com" \
--header "Content-Type: application/json" \
--data '{
"action": "register_persona",
"persona": "example.com",
"operator_did": "did:openpayload:1111111111111111111111",
"controller_keys": [
"did:openpayload:1111111111111111111111#keys-1"
],
"controller_threshold": 1,
"delivery_constraints": {
"requested_cache_seconds": 86400,
"max_http_envelope_bytes": 26214400,
"max_unchunked_message_bytes": 16777216,
"max_chunk_bytes": 2097152,
"max_replicas": 2
},
"challenge_id": "<challenge-id>",
"verification_expires_at": 1796083200000,
"nonce": "<operator-nonce>",
"valid_until": "<epoch-milliseconds>",
"signer_key_id": "did:openpayload:1111111111111111111111#keys-1",
"attestor": "0x<directory-attestor-account>",
"attestation_signature": "0x<directory-attestation-signature>",
"canonical_payload": "0x<canonical-payload-from-verification>",
"signature": "<base64-ed25519-signature>"
}'
Personas
Submit a Persona registration or renewal
Sign and submit the canonical DNS-attested Persona payload prepared by a Directory
curl --request PUT \
--url "https://directory.example.com/personas/example.com" \
--header "Content-Type: application/json" \
--data '{
"action": "register_persona",
"persona": "example.com",
"operator_did": "did:openpayload:1111111111111111111111",
"controller_keys": [
"did:openpayload:1111111111111111111111#keys-1"
],
"controller_threshold": 1,
"delivery_constraints": {
"requested_cache_seconds": 86400,
"max_http_envelope_bytes": 26214400,
"max_unchunked_message_bytes": 16777216,
"max_chunk_bytes": 2097152,
"max_replicas": 2
},
"challenge_id": "<challenge-id>",
"verification_expires_at": 1796083200000,
"nonce": "<operator-nonce>",
"valid_until": "<epoch-milliseconds>",
"signer_key_id": "did:openpayload:1111111111111111111111#keys-1",
"attestor": "0x<directory-attestor-account>",
"attestation_signature": "0x<directory-attestation-signature>",
"canonical_payload": "0x<canonical-payload-from-verification>",
"signature": "<base64-ed25519-signature>"
}'
Submit the final operator signature for a Persona registration or DNS renewal. You must first complete Verify a Persona DNS challenge through the same Directory deployment.
The verification response contains a
For renewal,
canonical_payload that already binds the DNS attestation, operation, nonces, operator DID, constraints, and expiration. A registration payload also binds the proposed controllers and threshold. A renewal preserves the finalized controller set instead of encoding a replacement; use the controller-rotation endpoint for changes. Decode and sign the returned bytes locally. Submit the bound intent fields again so the Directory can reconstruct and compare the payload; do not alter them between verification and submission.
Persona v1 requires controller_threshold to equal 1. The controller set can contain more than one authorized verification-method ID, but each current update carries one active-controller signature.
Request
string
required
Persona prepared by the verified challenge.
string
Optional body copy of the path Persona. When supplied, it must match after normalization.
string
required
Verified, unused challenge ID.
string
required
register_persona or renew_persona, exactly as verified.string
required
Operator DID bound to the DNS challenge.
string[]
Controller set from the verified intent. Required for registration; renewal must omit it or repeat the finalized set exactly.
integer
Must equal
1 when supplied.object
Requested constraints from the verified intent. Omit
effective_ttl_seconds.integer
required
Unix-millisecond DNS-verification expiration from the verified intent.
string
required
Operator nonce used to build the verified intent.
string
required
Authorization expiration used to build the verified intent.
string
required
Directory attestor account returned by challenge verification.
string
required
Directory attestation signature returned by challenge verification.
string
required
Exact value returned by challenge verification, encoded as
0x-prefixed hexadecimal.string
required
Same verification-method ID declared during verification.
string
required
Ed25519 signature over the decoded canonical payload bytes, encoded as hexadecimal or Base64.
curl --request PUT \
--url "https://directory.example.com/personas/example.com" \
--header "Content-Type: application/json" \
--data '{
"action": "register_persona",
"persona": "example.com",
"operator_did": "did:openpayload:1111111111111111111111",
"controller_keys": [
"did:openpayload:1111111111111111111111#keys-1"
],
"controller_threshold": 1,
"delivery_constraints": {
"requested_cache_seconds": 86400,
"max_http_envelope_bytes": 26214400,
"max_unchunked_message_bytes": 16777216,
"max_chunk_bytes": 2097152,
"max_replicas": 2
},
"challenge_id": "<challenge-id>",
"verification_expires_at": 1796083200000,
"nonce": "<operator-nonce>",
"valid_until": "<epoch-milliseconds>",
"signer_key_id": "did:openpayload:1111111111111111111111#keys-1",
"attestor": "0x<directory-attestor-account>",
"attestation_signature": "0x<directory-attestation-signature>",
"canonical_payload": "0x<canonical-payload-from-verification>",
"signature": "<base64-ed25519-signature>"
}'
Response
202 Response
{
"status": "accepted",
"persona": "example.com",
"operator_did": "did:openpayload:1111111111111111111111",
"extrinsic": "apply_persona_with_proof",
"operation": "register_persona",
"tx_hash": "<transaction-hash>"
}
operation is renew_persona. The finalized renewal can reactivate an expired or revoked Persona under its existing operator. 202 Accepted confirms chain submission, not finalization. Read the Persona until its revision, active, verified_at, and verification_expires_at reflect the finalized operation.
Straight to the point
PUT /personas/{persona}
- Prerequisite: verified DNS challenge through the same Directory deployment
- Sign: decoded
canonical_payloadreturned by verification - Challenge: single-use
- Accepted submission:
202

