Version: 1.0.0 Verified: All examples verified against actual code repositories and live deployments
These are working API examples for all Structs APIs: the consensus network API, the web application API, the RPC API, NATS streaming, and client libraries in TypeScript and Python. Each example has been verified against real deployments.
Base URL: http://localhost:1317
Base path: /structs
{
"method": "GET",
"url": "http://localhost:1317/structs/player/1-1",
"headers": {
"Accept": "application/json"
}
}
Response:
{
"player": {
"id": "1-1",
"primaryAddress": "structs1...",
"playerId": "1-1"
},
"gridAttributes": {},
"playerInventory": {},
// online derived from capacity/load — no halted field
}
curl -s http://localhost:1317/structs/player/1-1 | jq
{
"method": "GET",
"url": "http://localhost:1317/structs/planet_by_player/1-1",
"headers": {
"Accept": "application/json"
}
}
Response:
{
"planet": [
{
"id": "1-1",
"ownerId": "1-1"
}
]
}
{
"method": "GET",
"url": "http://localhost:1317/blockheight",
"headers": {
"Accept": "application/json"
}
}
Response:
{
"height": 12345
}
{
"method": "GET",
"url": "http://localhost:1317/structs/player?pagination.key=&pagination.limit=100",
"headers": {
"Accept": "application/json"
}
}
Response:
{
"player": [],
"pagination": {
"next_key": null,
"total": "0"
}
}
Base URL: http://localhost:8080
Base path: /api
{
"method": "GET",
"url": "http://localhost:8080/api/player/1-1",
"headers": {
"Accept": "application/json"
}
}
{
"method": "GET",
"url": "http://localhost:8080/api/guild/0-1",
"headers": {
"Accept": "application/json"
}
}
{
"method": "GET",
"url": "http://localhost:8080/api/planet/1-1/shield/health",
"headers": {
"Accept": "application/json"
}
}
Sign the message LOGIN_GUILD{guildId}ADDRESS{address}DATETIME{unix_timestamp} with the address’s key; there is no username/password.
{
"method": "POST",
"url": "http://localhost:8080/api/auth/login",
"headers": {
"Content-Type": "application/json"
},
"body": {
"address": "structs1...",
"signature": "base64-signature",
"pubkey": "base64-pubkey",
"guild_id": "0-1",
"unix_timestamp": "1715000000"
}
}
Response:
{
"status": 200,
"headers": {
"Set-Cookie": "PHPSESSID=..."
},
"body": {
"success": true,
"errors": {},
"data": null
}
}
Base URL: http://localhost:26657
{
"method": "GET",
"url": "http://localhost:26657/status",
"headers": {
"Accept": "application/json"
}
}
Response:
{
"jsonrpc": "2.0",
"id": -1,
"result": {
"node_info": {},
"sync_info": {},
"validator_info": {}
}
}
{
"method": "GET",
"url": "http://localhost:26657/block?height=12345",
"headers": {
"Accept": "application/json"
}
}
GRASS uses NATS messaging for real-time streaming. Connect via native NATS protocol or WebSocket wrapper.
Connection URL: nats://localhost:4222
Subscribe to player updates on subject structs.player.1.
Connection URL: ws://localhost:1443
const ws = new WebSocket('ws://localhost:1443');
ws.send(JSON.stringify({
action: 'subscribe',
subjects: ['structs.player.1', 'structs.planet.1-1']
}));
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log('Subject:', message.subject);
console.log('Data:', message.data);
};
| Pattern | Description | Example |
|---|---|---|
structs.player.* |
Player-specific updates | structs.player.1 |
structs.planet.* |
Planet-specific updates | structs.planet.1-1 |
structs.guild.* |
Guild-specific updates | structs.guild.1 |
structs.struct.* |
Struct-specific updates | structs.struct.1 |
structs.fleet.* |
Fleet-specific updates | structs.fleet.1 |
structs.global |
Global game state updates | N/A |
You build the TypeScript client yourself from the structsd repo using its make system, which generates the proto bindings with ts-proto via buf:
git clone https://github.com/playstructs/structsd.git
cd structsd
make proto-gen-ts # TypeScript proto/message bindings (ts-proto via buf)
make proto-swagger # optional: OpenAPI/Swagger spec for the REST API
Use the generated message and service types with CosmJS (SigningStargateClient plus a registry of the generated types) to sign and broadcast transactions. For reads, direct HTTP against the REST endpoints is the simplest and most reliable path.
Query game state with plain HTTP requests:
const response = await fetch('http://localhost:1317/structs/player/1-1');
const data = await response.json();
console.log('Player:', data.player);
import requests
response = requests.get('http://localhost:1317/structs/player/1-1')
data = response.json()
print('Player:', data['player'])
import requests
response = requests.get('http://localhost:1317/blockheight')
data = response.json()
print('Block Height:', data['height'])
import asyncio
from nats.aio.client import Client as NATS
async def main():
nc = NATS()
await nc.connect('nats://localhost:4222')
async def message_handler(msg):
print(f'Subject: {msg.subject}')
print(f'Data: {msg.data.decode()}')
await nc.subscribe('structs.player.1', cb=message_handler)
await asyncio.sleep(3600)
await nc.close()
asyncio.run(main())
Build game state step by step:
GET /blockheight – store as gameState.blockHeightGET /structs/player – store as gameState.playersGET /structs/planet_by_player/{playerId} – store as gameState.planets[playerId]async function queryWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url);
if (response.ok) {
return await response.json();
}
if (response.status === 404) {
return null;
}
if (response.status >= 500 && i < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
continue;
}
throw new Error(`HTTP ${response.status}`);
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
Static data (TTL: 3600s, safe to cache):
GET /structs/struct_typeGET /api/struct/typeGET /api/guild/directoryDynamic data (do not cache):
GET /blockheightGET /api/player/{player_id}/ore/statsGET /api/planet/{planet_id}/shield/health/structs/ prefix (not /cosmos/game/v1beta1/)/api/ prefix (not /api/v1/)nats://localhost:4222 or ws://localhost:1443structsd repo via make proto-gen-ts. For reads, prefer direct HTTP requests for reliability; use the generated bindings with CosmJS for signing.