API Overview
This section provides comprehensive documentation for the NuNet Device Management Service API.
Server Configuration
The REST server by default binds to 127.0.0.1 on port 9999. The configuration can be changed via the dms_config.json file using the rest.port and rest.addr parameters.
All API endpoints are accessed using the following base URL format:
http://<host>:<port>/api/v1/<endpoint>
API Endpoints
Health and Configuration
Health Check
GET /health
Returns the health status of the API server.
Response:
{
"status": "ok"
}
Status Codes:
200 OK: Server is healthy
Get Configuration
GET /config
Returns the DMS configuration. This endpoint is only available when the server is running in debug mode.
Response (Debug Mode):
{
"config": {
// Full DMS configuration object
}
}
Response (Non-Debug Mode):
{
"config": "allowed in debug mode"
}
Status Codes:
200 OK: Configuration returned successfully
Actor Management
The Device Management Service uses an actor-based architecture for message passing and distributed communication. All actor endpoints are under /api/v1/actor.
Get Actor Handle
GET /api/v1/actor/handle
Retrieves the actor handle for the DMS node, containing the actor ID, DID (Decentralized Identifier), and network address information.
Response:
{
"id": "actor-id-string",
"did": "did:key:...",
"addr": {
"host": "12D3KooW...",
"inbox": "root"
}
}
Status Codes:
200 OK: Actor handle retrieved successfully500 Internal Server Error: Host node hasn't been initialized yet500 Internal Server Error: Handle ID is invalid
Send Message to Actor
POST /api/v1/actor/send
Sends a message to a specific actor without waiting for a response (fire-and-forget).
Request Body:
{
"to": {
"id": "destination-actor-id",
"did": "did:key:...",
"addr": {
"host": "12D3KooW...",
"inbox": "target-inbox"
}
},
"be": "/dms/node/peers/ping",
"from": {
"id": "source-actor-id",
"did": "did:key:...",
"addr": {
"host": "12D3KooW...",
"inbox": "root"
}
},
"nonce": 1234567890,
"opt": {
"exp": 1642248000000000000,
"topic": "/nunet/hello"
},
"msg": "base64-encoded-message-bytes",
"cap": "base64-encoded-capability-token",
"sig": "base64-encoded-signature"
}
Response:
{
"message": "message sent"
}
Status Codes:
200 OK: Message sent successfully400 Bad Request: Invalid request data500 Internal Server Error: Host node hasn't been initialized yet500 Internal Server Error: Failed to marshal message500 Internal Server Error: Destination address can't be resolved500 Internal Server Error: Failed to send message to destination
Invoke Actor Behavior
POST /api/v1/actor/invoke
Invokes a behavior on an actor and waits for a response. This is a synchronous request-response pattern.
Request Body:
{
"to": {
"id": "destination-actor-id",
"did": "did:key:...",
"addr": {
"host": "12D3KooW...",
"inbox": "target-inbox"
}
},
"be": "/dms/node/peers/ping",
"from": {
"id": "source-actor-id",
"did": "did:key:...",
"addr": {
"host": "12D3KooW...",
"inbox": "root"
}
},
"nonce": 1234567890,
"opt": {
"exp": 1642248000000000000,
"cont": "/dms/actor/replyto/1234567890"
},
"msg": "base64-encoded-message-bytes",
"cap": "base64-encoded-capability-token",
"sig": "base64-encoded-signature"
}
Response: Returns an enveloped response message in the same format as the request:
{
"to": { ... },
"be": "/dms/actor/replyto/1234567890",
"from": { ... },
"nonce": 9876543210,
"opt": { ... },
"msg": "base64-encoded-response-bytes",
"cap": "base64-encoded-capability-token",
"sig": "base64-encoded-signature"
}
Status Codes:
200 OK: Invocation successful, response returned400 Bad Request: Invalid request data408 Request Timeout: Request timed out waiting for response500 Internal Server Error: Host node hasn't been initialized yet500 Internal Server Error: Failed to marshal message500 Internal Server Error: Destination address can't be resolved500 Internal Server Error: Failed to send message to destination
Broadcast Message
POST /api/v1/actor/broadcast
Broadcasts a message to a pubsub topic. All actors subscribed to the topic will receive the message and can respond.
Request Body:
{
"to": {},
"be": "/broadcast/hello",
"from": {
"id": "source-actor-id",
"did": "did:key:...",
"addr": {
"host": "12D3KooW...",
"inbox": "root"
}
},
"nonce": 1234567890,
"opt": {
"exp": 1642248000000000000,
"topic": "/nunet/hello"
},
"msg": "base64-encoded-message-bytes",
"cap": "base64-encoded-capability-token",
"sig": "base64-encoded-signature"
}
Response: Returns an array of response envelopes from actors that responded:
[
{
"to": { ... },
"be": "/dms/actor/replyto/1234567890",
"from": { ... },
"nonce": 9876543210,
"opt": { ... },
"msg": "base64-encoded-response-bytes",
"cap": "base64-encoded-capability-token",
"sig": "base64-encoded-signature"
}
]
Status Codes:
200 OK: Broadcast successful, responses collected400 Bad Request: Invalid request data or message is not a broadcast message500 Internal Server Error: Host node hasn't been initialized yet500 Internal Server Error: Failed to marshal message500 Internal Server Error: Failed to publish message
Message Envelope Structure
All actor messages use a standard envelope format:
Envelope Fields
to(Handle, required): The destination actor's handlebe(string, required): The behavior/endpoint to invokefrom(Handle, required): The source actor's handlenonce(uint64, required): A unique nonce for the messageopt(EnvelopeOptions, required): Options for message processingmsg([]byte, required): The message payload as base64-encoded bytescap([]byte, optional): Capability token for authorizationsig([]byte, optional): Cryptographic signature for message verification
Handle Structure
id(string): Actor identifierdid(string): Decentralized Identifieraddr(Address): Network address informationhost(string): LibP2P peer IDinbox(string): Inbox address for message routing
EnvelopeOptions Structure
exp(uint64): Expiration timestamp in nanoseconds since Unix epochcont(string, optional): Reply-to continuation/behavior name (required for invoke)topic(string, optional): Pubsub topic for broadcast messages (required for broadcast)
Error Handling
The API uses standard HTTP status codes and returns error details in JSON format.
Error Response Format
{
"error": "error message describing what went wrong"
}
Common Error Codes
400 Bad Request: Invalid request format or parameters408 Request Timeout: Request timed out (invoke/broadcast only)500 Internal Server Error: Server error (host not initialized, message send failure, etc.)
CORS Configuration
The API server is configured with CORS support. The default configuration allows:
- Origins:
http://localhost:9991,http://localhost:9992 - Methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
- Headers: Access-Control-Allow-Origin, Origin, Content-Length, Content-Type
- Credentials: Not allowed
- Max Age: 12 hours
Security Note: The current CORS configuration allowing localhost origins is a security risk and should be configured appropriately for production environments.
Client Library
A Go client library is available for interacting with the DMS API. The client is part of the device-management-service repository.
Go Client Example
package main
import (
"context"
"fmt"
"log"
"time"
"gitlab.com/nunet/device-management-service/client"
"gitlab.com/nunet/device-management-service/actor"
)
func main() {
// Create client configuration
cfg := client.Config{
Host: "localhost:9999",
Protocol: client.ConnectionTCP,
APIPrefix: "/api/v1",
Version: "v1",
}
// Create security context (required for actor operations)
securityCtx, err := client.NewClientSecurityContext(privateKeyReader, capabilityReader)
if err != nil {
log.Fatal(err)
}
// Create client
cli, err := client.NewClient(cfg, securityCtx)
if err != nil {
log.Fatal(err)
}
// Get DMS handle
handle, err := cli.GetDMSHandle(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Printf("DMS Handle: %+v\n", handle)
// Send a message
result, err := cli.SendMessage(
context.Background(),
"/dms/node/peers/ping",
map[string]interface{}{"ping": "pong"},
client.WithTimeout(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Message sent: %+v\n", result)
}
For more information about available behaviors and capabilities, see Code Reference.