Network Topology (Net3D) API Reference
This guide gives you everything you need to push data into GIIP's Network Topology (Net3D) visualization โ read it once and you can start inserting data immediately.
โ ๏ธ Scope of this document โ read this first
This document describes the procedure for the network topology of servers and databases only. The two formats documented here (
netstat,db_connections) are the only two formats the Net3D screen reads.If you want to display arbitrary non-network data (order flows, org charts, service dependencies and the like) in this 3D layout โ read Appendix: Displaying Non-Network Data in This Layout first. Simply changing
kFactorto an arbitrary value and pushing it into tKVS does not work โ the write succeeds withRstVal 200, but the screen shows nothing at all, and raises no error.
Prerequisites
| Item | Description | How to Obtain |
|---|---|---|
| SK (Secret Key) | Secret key used for API authentication | Available from the lsvrdetail (server detail) or corpgroup (corporation/group management) page in the GIIP admin console |
| API URL | Your GIIP server address | Example: https://your-api.azurewebsites.net |
| LSSN | Unique session number issued after server registration | Retrieved from the response in Step 1 |
What is LSSN?
LSSN (Long-term Session Serial Number) is a numeric ID that identifies a single server. When you register a server for the first time via AgentAutoRegister, a unique LSSN is issued for that server. You then use this LSSN as the kKey value in all subsequent KVSPut data submissions.
Flow summary:
Register server (AgentAutoRegister) โ Receive LSSN โ Use LSSN as kKey for netstat/db_connections submissions
Authentication
- Content-Type:
application/x-www-form-urlencoded - Auth location: Include the SK in the
tokenfield of the request body โ NOT in an HTTP header - Wrong:
Authorization: Bearer YOUR_SK(not supported) - Correct: Include
token=YOUR_SKin the request body
Step 1: Register the Server (AgentAutoRegister) โ Obtain LSSN
Register a server with GIIP and receive an LSSN. Save this LSSN โ you will need it for every subsequent call.
- Endpoint:
POST https://YOUR_API_URL/api/giipApi?cmd=AgentAutoRegister - Content-Type:
application/x-www-form-urlencoded
Request Body Fields:
| Field | Value |
|---|---|
token | YOUR_SK |
text | AgentAutoRegister |
jsondata | Serialized JSON string (see example below) |
jsondata example:
{
"hostname": "WEB-SRV-01",
"os": "Windows Server 2022",
"cpu_cores": 8,
"ipv4_local": "10.0.0.5"
}
curl example:
curl -X POST "https://YOUR_API_URL/api/giipApi?cmd=AgentAutoRegister" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "token=YOUR_SK" \
--data-urlencode "text=AgentAutoRegister" \
--data-urlencode 'jsondata={"hostname":"WEB-SRV-01","os":"Windows Server 2022","cpu_cores":8,"ipv4_local":"10.0.0.5"}'
Response example:
{
"RstVal": 200,
"RstMsg": "Success",
"lssn": 123456
}
Important: Save the
lssnvalue from the response (e.g.,123456). It is used askKeyin every Step 2 and Step 3 request.
Step 2: Submit Server Connections (netstat KVSPut)
Send TCP connection information from the current server to external servers.
- Endpoint:
POST https://YOUR_API_URL/api/giipApi(nocmdquery parameter) - Content-Type:
application/x-www-form-urlencoded
Request Body Fields:
| Field | Value | Description |
|---|---|---|
token | YOUR_SK | Authentication key |
text | KVSPut kType kKey kFactor | Literal fixed string โ copy exactly as shown |
jsondata | Serialized JSON string (see example below) | Actual connection data |
jsondata example:
{
"kType": "lssn",
"kKey": "123456",
"kFactor": "netstat",
"kValue": [
{
"remote_ip": "10.0.0.10",
"remote_port": 8080,
"process_name": "nginx.exe",
"state": "ESTABLISHED"
},
{
"remote_ip": "10.0.0.20",
"remote_port": 3306,
"process_name": "myapp.exe",
"state": "ESTABLISHED"
}
]
}
curl example:
curl -X POST "https://YOUR_API_URL/api/giipApi" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "token=YOUR_SK" \
--data-urlencode "text=KVSPut kType kKey kFactor" \
--data-urlencode 'jsondata={"kType":"lssn","kKey":"123456","kFactor":"netstat","kValue":[{"remote_ip":"10.0.0.10","remote_port":8080,"process_name":"nginx.exe","state":"ESTABLISHED"}]}'
Response example:
{
"RstVal": 200,
"RstMsg": "Success"
}
kValue field reference:
| Field | Type | Description |
|---|---|---|
remote_ip | string | IP address of the destination server |
remote_port | integer | Port of the destination server |
process_name | string | Name of the process that owns the connection |
state | string | Connection state. Only ESTABLISHED entries appear as links on the topology |
Note: Only entries where
stateisESTABLISHEDare rendered as connection lines in the topology view.
Step 3: Submit DB Connection Data (db_connections KVSPut)
Send query and load information from an application server to a database server.
- Endpoint:
POST https://YOUR_API_URL/api/giipApi(same endpoint as netstat) - Content-Type:
application/x-www-form-urlencoded
Request Body Fields:
| Field | Value | Description |
|---|---|---|
token | YOUR_SK | Authentication key |
text | KVSPut kType kKey kFactor | Literal fixed string โ copy exactly as shown |
jsondata | Serialized JSON string (see example below) | Actual DB connection data |
jsondata example:
{
"kType": "lssn",
"kKey": "123456",
"kFactor": "db_connections",
"kValue": [
{
"client_net_address": "10.0.0.5",
"program_name": "MyApp.exe",
"cpu_load": 15,
"last_sql": "SELECT * FROM users WHERE id = 1",
"query_hash": "0xAB12CD34"
},
{
"client_net_address": "10.0.0.5",
"program_name": "MyApp.exe",
"cpu_load": 42,
"last_sql": "UPDATE orders SET status = 'shipped' WHERE order_id = 9901",
"query_hash": "0xCD56EF78"
}
]
}
curl example:
curl -X POST "https://YOUR_API_URL/api/giipApi" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "token=YOUR_SK" \
--data-urlencode "text=KVSPut kType kKey kFactor" \
--data-urlencode 'jsondata={"kType":"lssn","kKey":"123456","kFactor":"db_connections","kValue":[{"client_net_address":"10.0.0.5","program_name":"MyApp.exe","cpu_load":15,"last_sql":"SELECT * FROM users WHERE id = 1","query_hash":"0xAB12CD34"}]}'
Response example:
{
"RstVal": 200,
"RstMsg": "Success"
}
kValue field reference:
| Field | Type | Description |
|---|---|---|
client_net_address | string | Source server IP. Must exactly match tManagedDatabase.db_host to create a DB link |
program_name | string | Executable name. Displayed as the Outgoing node label in the topology |
cpu_load | integer | Query load (%). Controls link line thickness and particle speed |
last_sql | string | Currently executing SQL statement. Displayed in the detail view modal |
query_hash | string | SQL statement hash. Used to group identical queries |
Step 4: Retrieve DB List (ManagedDatabaseList)
Retrieve the list of managed databases registered in the project.
- Endpoint:
POST https://YOUR_API_URL/api/giipApi - Content-Type:
application/x-www-form-urlencoded
Request Body Fields:
| Field | Value |
|---|---|
token | YOUR_SK |
text | ManagedDatabaseList mssql (specify db_type as needed) |
curl example:
curl -X POST "https://YOUR_API_URL/api/giipApi" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "token=YOUR_SK" \
--data-urlencode "text=ManagedDatabaseList mssql"
Response example:
{
"RstVal": 200,
"RstMsg": "Success",
"data": [
{
"db_host": "10.0.0.30",
"db_name": "ProductionDB",
"db_type": "mssql"
}
]
}
The SK embedded in
tokencarries the project context, so you do not need to passcsnseparately โ the server resolves it automatically.
Full Example Scripts by Language
The full PowerShell / Bash / Python example scripts have been moved to a separate guide for length.
๐ Network Topology (Net3D) Full Example Scripts by Language
Verification
After running a script, follow these steps to confirm data was received correctly.
- Server registration: Go to
Core Management > Server Inventoryand confirm the server appears with the correct hostname. - DB mapping: Verify that
client_net_addressexactly matches thedb_hostvalue intManagedDatabase. - Topology viewer: Navigate to
/admin/network-topologyand check whether connection lines between nodes are active. Data is typically reflected within 1โ2 minutes of transmission.
Data Integrity Rules
Verify the following conditions before or after inserting data.
- IP mapping: The
tLSvr.ipsfield must be a JSON array in the form[{"CIDR":"10.0.0.5/24"}]. A plain string causes the node to appear as 'External' in the topology. - DB host match: The
client_net_addressindb_connectionsmust be an exact text match (including case and whitespace) oftManagedDatabase.db_hostfor a DB link to be created. - JSON Depth: When serializing jsondata that contains a
kValuearray, use Depth 10 or higher. Insufficient depth truncates nested objects. - state value: Only
netstatentries wherestateequalsESTABLISHEDare rendered as connection lines in the topology. kFactorcannot be changed: The lookup SP (pApiNet3dDatabyAK) is hard-coded to read only the two literalsnetstatanddb_connections. If you KVSPut with an arbitrarykFactor(for examplemy_graph), the response isRstVal 200(stored successfully), but nothing appears on the topology screen, and no error is raised. tKVS itself is a general-purpose store that accepts any value, so do not mistake a successful write for "it will show up on screen".kKeymust be an already-registered asset ID: Fornetstat,kKeymust be atLSvr.LSsnregistered under the current CSN; fordb_connections, it must be atManagedDatabase.mdb_id. If you put an arbitrary unregistered key (an order number, an account ID and the like) intokKey, that row is silently excluded from the lookup.
Troubleshooting
Response RstVal is not 200
| RstVal | Meaning | Action |
|---|---|---|
| 401 | Authentication failed | Verify the token value (SK). Confirm it is in the request body, not an HTTP header |
| 400 | Bad request | Verify the text field is exactly KVSPut kType kKey kFactor (literal string) |
| 500 | Server error | Validate jsondata is well-formed JSON. Check for unescaped quotes inside the string |
No connection lines appear in the topology
- Confirm the
statevalue innetstatkValue items is exactlyESTABLISHED(uppercase). - Confirm
client_net_addressindb_connectionsis an exact match of the DB host IP registered in GIIP. - Confirm
tLSvr.ipsis a JSON array ([{"CIDR":"..."}]), not a plain string.
LSSN was lost
Call AgentAutoRegister again with the same hostname. The server returns the existing LSSN as long as the hostname is unique per server.
jsondata is being truncated in curl
Use --data-urlencode instead of -d. This safely URL-encodes JSON strings that contain special characters. For very large payloads, switch to the giipApiSk3 endpoint (see below).
Python NameError for undefined variable
This guide's Python examples use a single variable named AT. Do not mix in a variable named SK โ it is not defined in these scripts.
High-fidelity Logging Endpoint (Sk3)
When transmitting thousands of connection entries or when you need detailed error diagnostics, use the giipApiSk3 endpoint.
- Endpoint:
https://giipfaw.azurewebsites.net/api/giipApiSk3 - Benefits: Prevents data truncation for large jsondata payloads; automatically records detailed agent environment information and stack traces on error for faster topology debugging.
- Usage: Use the same request format as the standard endpoint โ just change the URL.
Appendix: Displaying Non-Network Data in This Layout (Generic Reuse)
The Short Answer First
A dedicated "generic graph" input path that accepts an arbitrary {nodes, links} payload as-is does not exist today.
(Design is in progress under giip #2526)
- โ What does not work: Changing
kFactorto an arbitrary value such asmy_graphand pushing{nodes, links}into tKVS. โ KVSPut returnsRstVal 200(tKVS is a general-purpose store that saves any kFactor). But the Net3D lookup SP does not read that row. The screen stays empty, with no error. - โ What does work today: If you map your entities to "servers" and your relations to "connections", you can draw an arbitrary directed graph right now. The procedure follows.
Mapping Rules โ Fitting Your Domain onto the Net3D Model
| Your data | How it is represented in Net3D | How to submit it |
|---|---|---|
| One entity (node) | One server node (sphere) | Register via AgentAutoRegister โ obtain an LSSN |
| The entity's display name | Node label | The hostname value becomes the node name as-is |
| The entity's unique identifier | Synthetic IP | Assign a non-overlapping IP to ipv4_local (e.g. 10.99.0.1) |
| One relation (edge) | Link line | Put the counterpart entity's synthetic IP in remote_ip of the netstat KVSPut |
| The relation's label | The link's process name | The process_name value |
๐ก You do not necessarily have to register the counterpart entity. If
remote_ipdoes not match the IP of any registered server, Net3D automatically creates an External node named after that IP. However, the name is then the raw IP string, so register any entity whose name you want to control viaAgentAutoRegister.
Input Schema
โ Register an entity โ AgentAutoRegister
| Field | Type | Required | Constraints | Example |
|---|---|---|---|---|
hostname | string | โ | Unique within the CSN. This value becomes the node label | "OrderIntake" |
ipv4_local | string | โ | A valid IPv4. Must be unique per entity for edges to connect correctly | "10.99.0.1" |
os | string | โ | Free-form string. Shown in the node details | "OrderFlow" |
cpu_cores | integer | โ | Display only | 1 |
โก Submit a relation โ KVSPut kType kKey kFactor
| Field | Type | Required | Constraints | Example |
|---|---|---|---|---|
kType | string | โ | Fixed to "lssn" | "lssn" |
kKey | string | โ | The source entity's LSSN. Ignored if it is not a registered LSsn | "123456" |
kFactor | string | โ | Fixed to "netstat". Any other value will not appear on screen | "netstat" |
kValue | array | โ | The array of edges | See below |
kValue[].remote_ip | string | โ | The destination entity's synthetic IP. 127.*/0.0.0.0/::1 are excluded | "10.99.0.2" |
kValue[].state | string | โ | Must be "ESTABLISHED" for an edge to be created ("ESTAB" is also accepted) | "ESTABLISHED" |
kValue[].process_name | string | โ | Displayed as the edge label | "PaymentRequest" |
kValue[].remote_port | integer | โ | Shown in the node bubble | 443 |
A Complete Copy-and-Paste Example โ A 3-Step Order Processing Flow
Change only the SK and API_URL lines and it runs as-is.
#!/bin/bash
set -e
SK="YOUR_SK"
API_URL="https://YOUR_API_URL"
# --- โ Register 3 entities as "servers" and obtain their LSSNs ---
register() {
curl -s -X POST "$API_URL/api/giipApi?cmd=AgentAutoRegister" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "token=$SK" \
--data-urlencode "text=AgentAutoRegister" \
--data-urlencode "jsondata={\"hostname\":\"$1\",\"os\":\"OrderFlow\",\"cpu_cores\":1,\"ipv4_local\":\"$2\"}"
}
LSSN_A=$(register "ORDERFLOW-OrderIntake" "10.99.0.1" | grep -oE '"lssn":[0-9]+' | cut -d: -f2)
LSSN_B=$(register "ORDERFLOW-PaymentApproval" "10.99.0.2" | grep -oE '"lssn":[0-9]+' | cut -d: -f2)
LSSN_C=$(register "ORDERFLOW-ShippingOrder" "10.99.0.3" | grep -oE '"lssn":[0-9]+' | cut -d: -f2)
echo "LSSN: A=$LSSN_A B=$LSSN_B C=$LSSN_C"
# --- โก Submit the relations (edges): OrderIntake โ PaymentApproval โ ShippingOrder ---
link() {
curl -s -X POST "$API_URL/api/giipApi" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "token=$SK" \
--data-urlencode "text=KVSPut kType kKey kFactor" \
--data-urlencode "jsondata={\"kType\":\"lssn\",\"kKey\":\"$1\",\"kFactor\":\"netstat\",\"kValue\":[{\"remote_ip\":\"$2\",\"remote_port\":443,\"process_name\":\"$3\",\"state\":\"ESTABLISHED\"}]}"
echo
}
link "$LSSN_A" "10.99.0.2" "PaymentRequest"
link "$LSSN_B" "10.99.0.3" "ShippingRequest"
After running it, open /en/network-topology and the three nodes OrderIntake โ PaymentApproval โ ShippingOrder
appear connected by edges (allow 1โ2 minutes for the data to be reflected).
How to Verify It Yourself
- Was it stored? โ Check that each KVSPut response is
{"RstVal":200}. - Is it read back? โ Verify directly through the API before opening the screen.
Thecurl -s -X POST "$API_URL/api/giipApi" \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "token=$SK" \ --data-urlencode "text=Net3dData csn" \ --data-urlencode "jsondata={\"csn\":YOUR_CSN,\"targetTime\":null}"hostnameyou just registered must appear insideserversin the response, and the synthetic IPs insidenetstat_data. If you cannot see them here, they will not appear on screen either โ check the failure cases below. - On screen โ Open
/en/network-topologyand check whether the node count / link count in the lower-right corner increased as expected.
Failure Cases and Their Symptoms
| What you did | Symptom | Cause | Resolution |
|---|---|---|---|
Set kFactor to an arbitrary value such as my_graph | RstVal 200, yet nothing changes on screen | The lookup SP reads only netstat/db_connections | Set kFactor to netstat |
Used an arbitrary ID (an order number and the like) as kKey | Stored successfully, no change on screen | kKey must be a registered LSsn | Obtain an LSSN via AgentAutoRegister first |
Put {"nodes":[...],"links":[...]} into kValue as-is | No change on screen | Net3D does not accept nodes/links as an input format | Follow the mapping rules above |
Set state to TIME_WAIT or similar | Nodes appear but there are no edges | Only ESTABLISHED/ESTAB becomes an edge | Use "ESTABLISHED" |
Used the same ipv4_local for every entity | The nodes merge into one | The IP is what identifies a node | Assign a unique IP to each entity |
Set remote_ip to 127.0.0.1 | No edges | Loopback/0.0.0.0/::1 are explicitly excluded | Use a real synthetic IP |
| A large graph with very many edges | Only part of it is shown, or the screen is entirely empty | The response is split into 2033-character chunks by FOR JSON | If you parse the response yourself, concatenate all JSON_... column fragments before parsing |
Limitations of This Workaround (Know Them Before You Rely on It)
- Every entity is drawn as a server node (sphere). You cannot use different shapes for different kinds of data.
- Clicking a node opens the server detail modal (not a screen showing your own domain information).
- Registered entities also appear in the server inventory list. They mix with real servers, so prefixing
hostname(for example withORDERFLOW-) to distinguish them is recommended. - Edge color and particle speed are based on CPU load, so they always look like the default state.
A generic entry point that takes an arbitrary {nodes, links} directly, without these limitations, is being designed under giip #2526.
Related Documents
Version: 1.5
Last Updated: 2026-09-14
Source: giipv3/public/help/api-network-topology.en.md