Manage the instance’s extra DID verification methods: P-256 keypairs HappyView generates, stores and publishes in its DID document. They appear in the did:web document HappyView serves, and a PLC sync adds them to a did:plc document. HappyView creates the #atproto_space method itself the first time a space is created.
const TOKEN = "hv_..."; // your API keyconst headers = { Authorization: `Bearer ${TOKEN}` };const TOKEN = "hv_..."; // your API keyconst headers = { Authorization: `Bearer ${TOKEN}` };let token = "hv_..."; // your API keyconst token = "hv_..." // your API key# All examples assume $TOKEN is an API key (hv_...)AUTH="Authorization: Bearer $TOKEN"List verification methods
Section titled “List verification methods”GET /admin/verification-methodsRequires settings:manage permission.
interface VerificationMethod { id: string; fragment_id: string; key_type: string; public_key_multibase: string; created_at: string;}
const response = await fetch("http://127.0.0.1:3000/admin/verification-methods", { headers,});const data: VerificationMethod[] = await response.json();const response = await fetch("http://127.0.0.1:3000/admin/verification-methods", { headers,});const data = await response.json();let response = client .get("http://127.0.0.1:3000/admin/verification-methods") .bearer_auth(token) .send() .await?;let data: serde_json::Value = response.json().await?;req, _ := http.NewRequest("GET", "http://127.0.0.1:3000/admin/verification-methods", nil)req.Header.Set("Authorization", "Bearer "+token)resp, err := http.DefaultClient.Do(req)if err != nil { log.Fatal(err)}defer resp.Body.Close()curl http://127.0.0.1:3000/admin/verification-methods -H "$AUTH"Response: 200 OK
[ { "id": "550e8400-e29b-41d4-a716-446655440000", "fragment_id": "#app_key", "key_type": "Multikey", "public_key_multibase": "zDnae...", "created_at": "2026-06-27T00:00:00.000000+00:00" }]Create a verification method
Section titled “Create a verification method”POST /admin/verification-methodsRequires settings:manage permission. Generates a new P-256 keypair. The private key is encrypted at rest with AES-256-GCM using TOKEN_ENCRYPTION_KEY.
const response = await fetch("http://127.0.0.1:3000/admin/verification-methods", { method: "POST", headers: { ...headers, "Content-Type": "application/json", }, body: JSON.stringify({ fragment_id: "#app_key", }),});const data: VerificationMethod = await response.json();const response = await fetch("http://127.0.0.1:3000/admin/verification-methods", { method: "POST", headers: { ...headers, "Content-Type": "application/json", }, body: JSON.stringify({ fragment_id: "#app_key", }),});const data = await response.json();let response = client .post("http://127.0.0.1:3000/admin/verification-methods") .bearer_auth(token) .json(&serde_json::json!({ "fragment_id": "#app_key" })) .send() .await?;let data: serde_json::Value = response.json().await?;body := bytes.NewBufferString(`{"fragment_id": "#app_key"}`)req, _ := http.NewRequest("POST", "http://127.0.0.1:3000/admin/verification-methods", body)req.Header.Set("Authorization", "Bearer "+token)req.Header.Set("Content-Type", "application/json")resp, err := http.DefaultClient.Do(req)if err != nil { log.Fatal(err)}defer resp.Body.Close()curl -X POST http://127.0.0.1:3000/admin/verification-methods \ -H "$AUTH" \ -H "Content-Type: application/json" \ -d '{"fragment_id": "#app_key"}'| Field | Type | Required | Description |
|---|---|---|---|
fragment_ | string | yes | DID document fragment identifier, must start with # followed by alphanumerics or underscores |
Returns 400 Bad Request for a malformed fragment_id: it must start with #, followed only by letters, digits and underscores. Returns 500 Internal Server Error if TOKEN_ENCRYPTION_KEY isn’t set, or if a method with that fragment_id already exists.
Response: 201 Created
{ "id": "550e8400-e29b-41d4-a716-446655440000", "fragment_id": "#app_key", "key_type": "Multikey", "public_key_multibase": "zDnae...", "created_at": "2026-06-27T00:00:00.000000+00:00"}Delete a verification method
Section titled “Delete a verification method”DELETE /admin/verification-methods/{fragment_id}Requires settings:manage permission.
const response = await fetch( "http://127.0.0.1:3000/admin/verification-methods/%23app_key", { method: "DELETE", headers },);const response = await fetch( "http://127.0.0.1:3000/admin/verification-methods/%23app_key", { method: "DELETE", headers },);client .delete("http://127.0.0.1:3000/admin/verification-methods/%23app_key") .bearer_auth(token) .send() .await?;req, _ := http.NewRequest("DELETE", "http://127.0.0.1:3000/admin/verification-methods/%23app_key", nil)req.Header.Set("Authorization", "Bearer "+token)resp, err := http.DefaultClient.Do(req)if err != nil { log.Fatal(err)}defer resp.Body.Close()curl -X DELETE http://127.0.0.1:3000/admin/verification-methods/%23app_key \ -H "$AUTH"The fragment_id path parameter is the fragment with or without its #: app_key and %23app_key both name #app_key.
Response: 204 No Content. Returns 404 Not Found if no method with that fragment ID exists.
© HappyProto

