SDK
The [R]DP SDKs are client packages for applications integrating with [R]DP platform APIs.
They provide generated service clients and shared behavior for transport, authentication configuration, logging, and optional timeouts.
Getting Started
Download the SDK package for your implementation language, choose the release that matches your target environment, install it with the normal tooling for that language, then use the generated client to call platform services.
The SDKs read RDP_SERVER_URL, RDP_SERVER_PORT, TLS_SKIP_VERIFY, RDP_CLIENT_ID, RDP_CLIENT_SECRET, and RDP_API_KEY from their standard configuration loaders.
The examples below are the same snippets used by the WDM Object and Action guides.
For the full operation set, see Object and Action.
Publish an Object
Use PublishObject to create or update a single Object.
package main
import (
"context"
"log"
"time"
"connectrpc.com/connect"
"google.golang.org/protobuf/types/known/timestamppb"
wdmsdk "github.com/raft-tech/raft-wdm-sdk-go"
pb "github.com/raft-tech/raft-wdm-sdk-go/gen/raft/wdm/v1"
svc "github.com/raft-tech/raft-wdm-sdk-go/gen/raft/wdm/v1/service"
)
func main() {
cfg, err := wdmsdk.LoadConfig()
if err != nil {
log.Fatal(err)
}
client, err := wdmsdk.NewFromConfig(cfg)
if err != nil {
log.Fatal(err)
}
updatedAt := time.Now().UTC()
_, err = client.ObjectService().PublishObject(context.Background(), connect.NewRequest(&svc.PublishObjectRequest{
Object: &pb.Object{
Id: "link16-track-47210",
Name: "TRACK-47210",
Status: pb.ObjectStatus_OBJECT_STATUS_ACTIVE,
Ttl: timestamppb.New(updatedAt.Add(5 * time.Minute)),
Provenance: &pb.ProvenanceRecord{
Name: "aegis-radar-07",
UpdatedAt: timestamppb.New(updatedAt),
},
},
}))
if err != nil {
log.Fatal(err)
}
}
import com.google.protobuf.Timestamp;
import com.raft.wdm.Wdm;
import com.raft.wdm.raft.wdm.v1.Object;
import com.raft.wdm.raft.wdm.v1.ObjectStatus;
import com.raft.wdm.raft.wdm.v1.ProvenanceRecord;
import com.raft.wdm.raft.wdm.v1.service.PublishObjectRequest;
import com.raft.wdm.v1.WdmV1Client;
import java.time.Instant;
public final class PublishObjectExample {
public static void main(String[] args) {
var options = Wdm.toOptions(Wdm.loadConfig(null, null));
var updatedAt = Instant.now();
try (var client = WdmV1Client.create(options)) {
var req = PublishObjectRequest.newBuilder()
.setObject(Object.newBuilder()
.setId("link16-track-47210")
.setName("TRACK-47210")
.setStatus(ObjectStatus.OBJECT_STATUS_ACTIVE)
.setTtl(timestamp(updatedAt.plusSeconds(300)))
.setProvenance(ProvenanceRecord.newBuilder()
.setName("aegis-radar-07")
.setUpdatedAt(timestamp(updatedAt))))
.build();
client.getObjectServiceBlocking()
.publishObjectBlocking(req)
.execute();
}
}
private static Timestamp timestamp(Instant instant) {
return Timestamp.newBuilder()
.setSeconds(instant.getEpochSecond())
.setNanos(instant.getNano())
.build();
}
}
import asyncio
from datetime import datetime, timedelta, timezone
from google.protobuf.timestamp_pb2 import Timestamp
from raft.wdm.v1 import object_pb2
from raft.wdm.v1 import common_pb2
from raft.wdm.v1.service import object_service_pb2
import raft_wdm_sdk
def timestamp(dt: datetime) -> Timestamp:
value = Timestamp()
value.FromDatetime(dt)
return value
async def main() -> None:
updated_at = datetime.now(timezone.utc)
async with raft_wdm_sdk.Client.from_config(raft_wdm_sdk.load_config()) as client:
await client.object_service.publish_object(
object_service_pb2.PublishObjectRequest(
object=object_pb2.Object(
id="link16-track-47210",
name="TRACK-47210",
status=object_pb2.OBJECT_STATUS_ACTIVE,
ttl=timestamp(updated_at + timedelta(minutes=5)),
provenance=common_pb2.ProvenanceRecord(
name="aegis-radar-07",
updated_at=timestamp(updated_at),
),
),
),
)
asyncio.run(main())
import { create } from "@bufbuild/protobuf";
import { timestampFromDate } from "@bufbuild/protobuf/wkt";
import { createClient, fromNodeConfig, loadConfig } from "@raft-tech/raft-wdm-sdk-typescript";
import { ObjectStatus } from "@raft-tech/raft-wdm-sdk-typescript/gen/raft/wdm/v1/object_pb.js";
import { PublishObjectRequestSchema } from "@raft-tech/raft-wdm-sdk-typescript/gen/raft/wdm/v1/service/object_service_pb.js";
const client = createClient(...fromNodeConfig(loadConfig()));
const updatedAt = new Date();
await client.objectService.publishObject(
create(PublishObjectRequestSchema, {
object: {
id: "link16-track-47210",
name: "TRACK-47210",
status: ObjectStatus.OBJECT_STATUS_ACTIVE,
ttl: timestampFromDate(new Date(updatedAt.getTime() + 5 * 60 * 1000)),
provenance: {
name: "aegis-radar-07",
updatedAt: timestampFromDate(updatedAt),
},
},
}),
);
curl -X POST "${RDP_SERVER_URL}/api/v1/wdm/objects" \
-H "X-API-KEY: ${RDP_API_KEY}" \
-H "Content-Type: application/json" \
--json @- <<JSON
{
"object": {
"id": "link16-track-47210",
"name": "TRACK-47210",
"status": "OBJECT_STATUS_ACTIVE",
"ttl": "2026-05-27T21:36:04Z",
"provenance": {
"name": "aegis-radar-07",
"updatedAt": "2026-05-27T21:31:04Z"
}
}
}
JSON
Search Objects
Use SearchObjects to retrieve a paginated snapshot of Objects that match your filters.
package main
import (
"connectrpc.com/connect"
"context"
"log"
wdmsdk "github.com/raft-tech/raft-wdm-sdk-go"
pb "github.com/raft-tech/raft-wdm-sdk-go/gen/raft/wdm/v1"
svc "github.com/raft-tech/raft-wdm-sdk-go/gen/raft/wdm/v1/service"
)
func main() {
cfg, err := wdmsdk.LoadConfig()
if err != nil {
log.Fatal(err)
}
client, err := wdmsdk.NewFromConfig(cfg)
if err != nil {
log.Fatal(err)
}
resp, err := client.ObjectService().SearchObjects(context.Background(), connect.NewRequest(&svc.SearchObjectsRequest{
Query: &svc.ObjectQuery{
Statuses: []pb.ObjectStatus{pb.ObjectStatus_OBJECT_STATUS_ACTIVE},
Affiliations: []pb.Affiliation{pb.Affiliation_AFFILIATION_FRIEND},
},
PageSize: 100,
}))
if err != nil {
log.Fatal(err)
}
for _, obj := range resp.Msg.GetObjects() {
log.Printf("found object: %s %s", obj.GetId(), obj.GetName())
}
}
import com.raft.wdm.Wdm;
import com.raft.wdm.raft.wdm.v1.Affiliation;
import com.raft.wdm.raft.wdm.v1.ObjectStatus;
import com.raft.wdm.raft.wdm.v1.service.ObjectQuery;
import com.raft.wdm.raft.wdm.v1.service.SearchObjectsRequest;
import com.raft.wdm.v1.WdmV1Client;
public final class SearchObjectsExample {
public static void main(String[] args) {
var options = Wdm.toOptions(Wdm.loadConfig(null, null));
try (var client = WdmV1Client.create(options)) {
var req = SearchObjectsRequest.newBuilder()
.setQuery(ObjectQuery.newBuilder()
.addStatuses(ObjectStatus.OBJECT_STATUS_ACTIVE)
.addAffiliations(Affiliation.AFFILIATION_FRIEND))
.setPageSize(100)
.build();
client.getObjectServiceBlocking()
.searchObjectsBlocking(req)
.execute();
}
}
}
import asyncio
from raft.wdm.v1 import assessment_pb2
from raft.wdm.v1 import object_pb2
from raft.wdm.v1.service import object_service_pb2
from raft.wdm.v1.service import query_pb2
import raft_wdm_sdk
async def main() -> None:
async with raft_wdm_sdk.Client.from_config(raft_wdm_sdk.load_config()) as client:
response = await client.object_service.search_objects(
object_service_pb2.SearchObjectsRequest(
query=query_pb2.ObjectQuery(
statuses=[object_pb2.OBJECT_STATUS_ACTIVE],
affiliations=[assessment_pb2.AFFILIATION_FRIEND],
),
page_size=100,
),
)
for obj in response.objects:
print(f"found object: {obj.id} {obj.name}")
asyncio.run(main())
import { create } from "@bufbuild/protobuf";
import { createClient, fromNodeConfig, loadConfig } from "@raft-tech/raft-wdm-sdk-typescript";
import { Affiliation } from "@raft-tech/raft-wdm-sdk-typescript/gen/raft/wdm/v1/assessment_pb.js";
import { ObjectStatus } from "@raft-tech/raft-wdm-sdk-typescript/gen/raft/wdm/v1/object_pb.js";
import { SearchObjectsRequestSchema } from "@raft-tech/raft-wdm-sdk-typescript/gen/raft/wdm/v1/service/object_service_pb.js";
const client = createClient(...fromNodeConfig(loadConfig()));
const response = await client.objectService.searchObjects(
create(SearchObjectsRequestSchema, {
query: {
statuses: [ObjectStatus.OBJECT_STATUS_ACTIVE],
affiliations: [Affiliation.AFFILIATION_FRIEND],
},
pageSize: 100,
}),
);
for (const object of response.objects) {
console.log(`found object: ${object.id} ${object.name}`);
}
curl -X POST "${RDP_SERVER_URL}/api/v1/wdm/objects/search" \
-H "X-API-KEY: ${RDP_API_KEY}" \
-H "Content-Type: application/json" \
--json @- <<JSON
{
"query": {
"statuses": ["OBJECT_STATUS_ACTIVE"],
"affiliations": ["AFFILIATION_FRIEND"]
},
"pageSize": 100
}
JSON
Create an Action
Use CreateAction to create a new Action with its routing, intent, priority, timing, and related Objects.
package main
import (
"context"
"log"
"time"
"connectrpc.com/connect"
"google.golang.org/protobuf/types/known/timestamppb"
wdmsdk "github.com/raft-tech/raft-wdm-sdk-go"
pb "github.com/raft-tech/raft-wdm-sdk-go/gen/raft/wdm/v1"
svc "github.com/raft-tech/raft-wdm-sdk-go/gen/raft/wdm/v1/service"
)
func main() {
cfg, err := wdmsdk.LoadConfig()
if err != nil {
log.Fatal(err)
}
client, err := wdmsdk.NewFromConfig(cfg)
if err != nil {
log.Fatal(err)
}
updatedAt := time.Now().UTC()
_, err = client.ActionService().CreateAction(context.Background(), connect.NewRequest(&svc.CreateActionRequest{
Action: &pb.Action{
Id: "isr-collect-alpha",
Name: "ISR Collection Alpha",
Type: "isr_collection",
Scope: pb.ActionScope_ACTION_SCOPE_TASK,
State: pb.ActionState_ACTION_STATE_ASSIGNED,
Priority: pb.ActionPriority_ACTION_PRIORITY_HIGH,
RequestedBy: &pb.Principal{
Id: "ops-cell-alpha",
Type: pb.PrincipalType_PRINCIPAL_TYPE_USER,
},
AssignedTo: &pb.Principal{
Id: "uav-shadow-07",
Type: pb.PrincipalType_PRINCIPAL_TYPE_OBJECT,
},
AuthorizedBy: &pb.Principal{
Id: "s2-battle-captain",
Type: pb.PrincipalType_PRINCIPAL_TYPE_USER,
},
Intent: &pb.Intent{
Purpose: "Observe NAI 3 before the convoy crosses phase line BLUE",
Method: "Maintain a collection orbit with EO/IR coverage",
EndState: "Report movement or changes near the route",
},
ObjectLinks: []*pb.ObjectLink{
{
ObjectId: "link16-track-47210",
Type: pb.ObjectLinkType_OBJECT_LINK_TYPE_TARGET,
},
},
Provenance: &pb.ProvenanceRecord{
Name: "ops-center-01",
UpdatedAt: timestamppb.New(updatedAt),
},
},
}))
if err != nil {
log.Fatal(err)
}
}
import com.google.protobuf.Timestamp;
import com.raft.wdm.Wdm;
import com.raft.wdm.raft.wdm.v1.Action;
import com.raft.wdm.raft.wdm.v1.ActionPriority;
import com.raft.wdm.raft.wdm.v1.ActionScope;
import com.raft.wdm.raft.wdm.v1.ActionState;
import com.raft.wdm.raft.wdm.v1.Intent;
import com.raft.wdm.raft.wdm.v1.ObjectLink;
import com.raft.wdm.raft.wdm.v1.ObjectLinkType;
import com.raft.wdm.raft.wdm.v1.Principal;
import com.raft.wdm.raft.wdm.v1.PrincipalType;
import com.raft.wdm.raft.wdm.v1.ProvenanceRecord;
import com.raft.wdm.raft.wdm.v1.service.CreateActionRequest;
import com.raft.wdm.v1.WdmV1Client;
import java.time.Instant;
public final class CreateActionExample {
public static void main(String[] args) {
var options = Wdm.toOptions(Wdm.loadConfig(null, null));
var updatedAt = Instant.now();
try (var client = WdmV1Client.create(options)) {
var req = CreateActionRequest.newBuilder()
.setAction(Action.newBuilder()
.setId("isr-collect-alpha")
.setName("ISR Collection Alpha")
.setType("isr_collection")
.setScope(ActionScope.ACTION_SCOPE_TASK)
.setState(ActionState.ACTION_STATE_ASSIGNED)
.setPriority(ActionPriority.ACTION_PRIORITY_HIGH)
.setRequestedBy(Principal.newBuilder()
.setId("ops-cell-alpha")
.setType(PrincipalType.PRINCIPAL_TYPE_USER))
.setAssignedTo(Principal.newBuilder()
.setId("uav-shadow-07")
.setType(PrincipalType.PRINCIPAL_TYPE_OBJECT))
.setAuthorizedBy(Principal.newBuilder()
.setId("s2-battle-captain")
.setType(PrincipalType.PRINCIPAL_TYPE_USER))
.setIntent(Intent.newBuilder()
.setPurpose("Observe NAI 3 before the convoy crosses phase line BLUE")
.setMethod("Maintain a collection orbit with EO/IR coverage")
.setEndState("Report movement or changes near the route"))
.addObjectLinks(ObjectLink.newBuilder()
.setObjectId("link16-track-47210")
.setType(ObjectLinkType.OBJECT_LINK_TYPE_TARGET))
.setProvenance(ProvenanceRecord.newBuilder()
.setName("ops-center-01")
.setUpdatedAt(timestamp(updatedAt))))
.build();
client.getActionService()
.createActionBlocking(req)
.execute();
}
}
private static Timestamp timestamp(Instant instant) {
return Timestamp.newBuilder()
.setSeconds(instant.getEpochSecond())
.setNanos(instant.getNano())
.build();
}
}
import asyncio
from datetime import datetime, timezone
from google.protobuf.timestamp_pb2 import Timestamp
from raft.wdm.v1 import action_pb2
from raft.wdm.v1 import common_pb2
from raft.wdm.v1.service import action_service_pb2
import raft_wdm_sdk
def timestamp(dt: datetime) -> Timestamp:
value = Timestamp()
value.FromDatetime(dt)
return value
async def main() -> None:
updated_at = datetime.now(timezone.utc)
async with raft_wdm_sdk.Client.from_config(raft_wdm_sdk.load_config()) as client:
await client.action_service.create_action(
action_service_pb2.CreateActionRequest(
action=action_pb2.Action(
id="isr-collect-alpha",
name="ISR Collection Alpha",
type="isr_collection",
scope=action_pb2.ACTION_SCOPE_TASK,
state=action_pb2.ACTION_STATE_ASSIGNED,
priority=action_pb2.ACTION_PRIORITY_HIGH,
requested_by=common_pb2.Principal(
id="ops-cell-alpha",
type=common_pb2.PRINCIPAL_TYPE_USER,
),
assigned_to=common_pb2.Principal(
id="uav-shadow-07",
type=common_pb2.PRINCIPAL_TYPE_OBJECT,
),
authorized_by=common_pb2.Principal(
id="s2-battle-captain",
type=common_pb2.PRINCIPAL_TYPE_USER,
),
intent=action_pb2.Intent(
purpose="Observe NAI 3 before the convoy crosses phase line BLUE",
method="Maintain a collection orbit with EO/IR coverage",
end_state="Report movement or changes near the route",
),
object_links=[
action_pb2.ObjectLink(
object_id="link16-track-47210",
type=action_pb2.OBJECT_LINK_TYPE_TARGET,
),
],
provenance=common_pb2.ProvenanceRecord(
name="ops-center-01",
updated_at=timestamp(updated_at),
),
),
),
)
asyncio.run(main())
import { create } from "@bufbuild/protobuf";
import { timestampFromDate } from "@bufbuild/protobuf/wkt";
import { createClient, fromNodeConfig, loadConfig } from "@raft-tech/raft-wdm-sdk-typescript";
import { PrincipalType } from "@raft-tech/raft-wdm-sdk-typescript/gen/raft/wdm/v1/common_pb.js";
import {
ActionPriority,
ActionScope,
ActionState,
ObjectLinkType,
} from "@raft-tech/raft-wdm-sdk-typescript/gen/raft/wdm/v1/action_pb.js";
import { CreateActionRequestSchema } from "@raft-tech/raft-wdm-sdk-typescript/gen/raft/wdm/v1/service/action_service_pb.js";
const client = createClient(...fromNodeConfig(loadConfig()));
const updatedAt = new Date();
await client.actionService.createAction(
create(CreateActionRequestSchema, {
action: {
id: "isr-collect-alpha",
name: "ISR Collection Alpha",
type: "isr_collection",
scope: ActionScope.TASK,
state: ActionState.ASSIGNED,
priority: ActionPriority.HIGH,
requestedBy: {
id: "ops-cell-alpha",
type: PrincipalType.USER,
},
assignedTo: {
id: "uav-shadow-07",
type: PrincipalType.OBJECT,
},
authorizedBy: {
id: "s2-battle-captain",
type: PrincipalType.USER,
},
intent: {
purpose: "Observe NAI 3 before the convoy crosses phase line BLUE",
method: "Maintain a collection orbit with EO/IR coverage",
endState: "Report movement or changes near the route",
},
objectLinks: [
{
objectId: "link16-track-47210",
type: ObjectLinkType.TARGET,
},
],
provenance: {
name: "ops-center-01",
updatedAt: timestampFromDate(updatedAt),
},
},
}),
);
curl -X POST "${RDP_SERVER_URL}/api/v1/wdm/actions" \
-H "X-API-KEY: ${RDP_API_KEY}" \
-H "Content-Type: application/json" \
--json @- <<JSON
{
"action": {
"id": "isr-collect-alpha",
"name": "ISR Collection Alpha",
"type": "isr_collection",
"scope": "ACTION_SCOPE_TASK",
"state": "ACTION_STATE_ASSIGNED",
"priority": "ACTION_PRIORITY_HIGH",
"requestedBy": {
"id": "ops-cell-alpha",
"type": "PRINCIPAL_TYPE_USER"
},
"assignedTo": {
"id": "uav-shadow-07",
"type": "PRINCIPAL_TYPE_OBJECT"
},
"authorizedBy": {
"id": "s2-battle-captain",
"type": "PRINCIPAL_TYPE_USER"
},
"intent": {
"purpose": "Observe NAI 3 before the convoy crosses phase line BLUE",
"method": "Maintain a collection orbit with EO/IR coverage",
"endState": "Report movement or changes near the route"
},
"objectLinks": [
{
"objectId": "link16-track-47210",
"type": "OBJECT_LINK_TYPE_TARGET"
}
],
"provenance": {
"name": "ops-center-01",
"updatedAt": "2026-05-27T21:31:04Z"
}
}
}
JSON