Developer Documentation V1
Stop building APIs for simple communication. Use a vertex.
Node Vertex is a programmable signaling fabric where every URL is a stateful, secure, and optionally intelligent endpoint. Use it to store values, signal events, hand off files, connect agents, coordinate devices, and build automation without creating another small API service or another MCP server.
brew tap nrun/tap
brew install nv
nv enroll
nv create hello --value "Every workflow starts with a vertex."
Notification and Action Vertices
Build alerts that can be acted on.
Notification Vertices tell humans, agents, and devices that something happened. Action Vertices let them securely respond from web, mobile, CLI, API, agents, App Vertex UI, or Polygon workflows.
nv notify create /acme/notify/legal
nv action create /acme/actions/legal/approve-doc \
--title "Approve Document" \
--role LegalReviewer \
--outcome approved \
--presentation approvalCard
nv notify send /acme/notify/legal \
--to /acme/users/u-123/phone \
--title "Legal review required" \
--body "Vendor MSA needs approval" \
--severity high \
--action /acme/actions/legal/approve-doc
nv action execute /acme/actions/legal/approve-doc \
--input '{"documentId":"doc_456","comment":"Approved"}'
Create notification and action vertices, send/list/read/ack notifications, execute actions, and register devices.
POST /api/notifications/send
POST /api/actions/{id}/executeExecute reusable Action Vertices through vertex-style paths for workflow and agent compatibility.
POST /v/acme/actions/legal/approve-doc
Represent phones, browsers, desktops, webhooks, email, Teams, and Slack as device vertices.
POST /api/devices/register
NodeVertex Mobile treats each phone install as a Device Vertex with a NodeRunner Resource Name (NRN), tenant membership, user identity, push-token binding, app version, trust state, TTL, and audit context. Push payloads are privacy-preserving wake-up hints only; the app fetches the current Notification Vertex and Action Vertex before showing or executing anything.
nrn:global:vertex:acme:device:iphone-17
nrn:global:id:acme:user:jane.admin-example.com
nrn:global:id:acme:membership:jane.admin-example.com
nrn:global:vertex:acme:notification-inbox:mobile
nrn:global:vertex:acme:action-inbox:mobile
nrn:global:vertex:acme:push-token:iphone-17
nrn:global:vertex:acme:action-execution:action_exec_123
nrn:global:vertex:acme:app-session:support-console
nrn:global:works:acme:workspace:legal-review
curl -X POST https://nodevertex.com/api/devices/register \
-H "Content-Type: application/json" \
-d '{
"tenantId":"acme",
"userId":"[email protected]",
"deviceId":"iphone-17",
"platform":"ios",
"pushProvider":"apns",
"pushToken":"rotating-platform-token",
"vertexPath":"acme/users/jane/devices/iphone-17",
"preferences":{
"deviceNrn":"nrn:global:vertex:acme:device:iphone-17",
"notificationInboxNrn":"nrn:global:vertex:acme:notification-inbox:mobile",
"actionInboxNrn":"nrn:global:vertex:acme:action-inbox:mobile",
"trustState":"trusted"
}
}'
Action Vertices are cards by default, not underlined links. Mobile, web, CLI, agents, App Vertex UI, and Polygon workflows can render or execute the same action contract while preserving TTL, policy, required input validation, confirmation behavior, and audit labels.
{
"variant": "incidentResponseCard",
"title": "Incident response",
"summary": "CPU saturation crossed the listener threshold.",
"icon": "IR",
"primaryActionLabel": "Escalate now",
"secondaryActionLabel": "Open war room",
"dangerActionLabel": "Rollback",
"confirmBeforeSubmit": true,
"requiresStepUpAuth": true,
"auditLabel": "incident.mobile_escalation",
"nextStatePreview": "On-call routing starts and the polygon timeline records the decision."
}
curl -X POST https://nodevertex.com/api/actions/act_123/execute \
-H "Content-Type: application/json" \
-d '{
"outcome":"Escalate now",
"sourceNotificationId":"notif_456",
"idempotencyKey":"iphone-17:act_123:notif_456:2026-06-17T12:00:00Z",
"actor":{
"type":"mobile-user",
"tenant":"acme",
"userId":"[email protected]",
"deviceId":"iphone-17",
"deviceNrn":"nrn:global:vertex:acme:device:iphone-17",
"userNrn":"nrn:global:id:acme:user:jane-example.com",
"membershipNrn":"nrn:global:id:acme:membership:jane-example.com"
},
"mobileAudit":{
"appSurface":"nodevertex-mobile",
"fetchedFreshBeforeExecution":true,
"pushPayloadTrusted":false
}
}'
App Vertex
Turn localhost into globalhost.
App Vertex lets you expose a local app, container, internal dashboard, API, or development preview through a secure Node Vertex URL. No public IP. No reverse proxy. No ingress YAML. No firewall changes.
Run your app anywhere, then make it reachable through the vertex fabric with one command. Node Vertex becomes the secure front door with HTTPS, Vertex Firewall policy, TTL, audit logging, and optional analytics.
# Start your local app
npm run dev
# Expose it through Node Vertex
nv app expose http://localhost:3000 --name myapp
# Share the secure URL
https://nodevertex.com/{tenant}/apps/myapp
Add controls as needed:
nv app expose http://localhost:3000 \
--name preview \
--expires 1h \
--auth passkey \
--analytics
Expose React, Vite, Next.js, ASP.NET, Rails, FastAPI, dashboards, admin tools, and local APIs.
nv app expose http://localhost:5000 --name dashboard
Expose a container port without publishing infrastructure directly to the internet.
nv app expose-container inventory-api --port 8080 --name inventory
Share demos and support sessions with expiring, policy-protected URLs.
nv app expose http://localhost:8080 --name demo --expires 30m
Why Node Vertex instead of MCP?
MCP gives agents a way to discover and call tools, but many production workflows do not need a full tool server. They need durable state, simple signaling, secure handoff, TTL, and audit trails. For those workflows, a vertex is simpler: it is a URL an agent can read or write from any runtime.
Store agent context and intermediate outputs as JSON vertices.
POST /agents/context-17
Publish results to operation-result vertices that humans and agents can read later.
GET /agents/result-88
Use shared HTTP verbs and per-vertex policy across tools, devices, agents, and workflows.
POST /acme/build-status
Vertex Firewall overview
Vertex Firewall adds policy to each URL: IP allowlists and denylists, CIDR restrictions, API keys, bearer tokens, tenant user auth, OIDC/SAML-ready identity, signed access tokens, method restrictions, TTL, rate limits, content-type validation, payload hashing, and audit logging.
policy /acme/build-status allow ip 203.0.113.0/24 require api-key methods GET, POST ttl 24h audit writes, auth-failures
What is a vertex?
A vertex is an addressable endpoint owned by a tenant. It has a key, type, authentication policy, lifecycle, current value or payload, optional TTL, optional event history, and optional specialized behavior such as append-only, read-once, write-once, mailbox, file, or operation-result semantics.
https://nodevertex.com/{tenant}/{vertexKey}
https://nodevertex.com/acme/build-status
Create a vertex
Create vertices through the API or admin UI. A minimal JSON vertex can be created with a tenant slug, key, type, access mode, and initial value.
curl -X POST https://nodevertex.com/api/v1/vertices \
-H "Content-Type: application/json" \
-d '{
"tenantSlug": "acme",
"vertexKey": "build-status",
"type": 2,
"accessMode": 1,
"value": "{\"status\":\"pending\"}"
}'
Read and write
Once created, the vertex is available through an intuitive tenant/key URL. GET reads. POST writes, appends, or signals depending on the vertex type. PUT replaces.
Write status
POST /acme/build-status
{ "status": "passed" }
Read status
GET /acme/build-status
{ "status": "passed" }
Signal events
A signal vertex is a URL that receives commands or events. It is ideal for automation triggers, device commands, agent coordination, and simple machine-to-machine notifications.
curl -X POST https://nodevertex.com/factory/reboot-device-17 \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"command":"reboot","issuedBy":"agent-01"}'
Authentication overview
| Mode | Use it for | Example |
|---|---|---|
| Public | Open values, public signals, demo endpoints | GET /demo/status |
| Bearer token | Server-to-server writes and reads | Authorization: Bearer {token} |
| Basic auth | Simple legacy integrations | Authorization: Basic ... |
| Tenant user | Admin and team-owned resources | Authenticated session |
| Signed access token | Expiring read/write links | ?token={signedToken} |
| OIDC / SAML | Enterprise federation | Designed for future policy providers |
Tenant API keys
API keys are tenant-scoped bearer credentials for automation. Create them in Account Security or with the CLI. Node Vertex stores only a SHA-256 hash of the token. Copy the raw token when it is created because it is never shown again.
nv api-key create --permissions read --name ci-reader
nv api-key create --permissions read,write --name deploy-bot --ttl-days 7
nv api-key list
nv api-key revoke <id>
Use the key with both the key id and bearer token:
curl https://nodevertex.com/api/v1/vertices?tenant=acme \
-H "X-NodeVertex-KeyId: acme-api-20260511100000" \
-H "Authorization: Bearer nvapi_..."
| Permission | Grants | Use it for |
|---|---|---|
read | tenant/content/vertex/conversation/app/form/analytics read scopes | GET, list, inspect, dashboards, reporting |
write | tenant/content/vertex/conversation/app/form write scopes | create, set, post, upload, app automation |
provisioning | tenant provisioning read/write scopes | tenant bootstrap and provisioning automation |
| granular scopes | vertex:read, vertex:create, vertex:write, conversation:post, etc. | least-privilege service accounts; post adds content to an existing conversation |
Free tier limits: one API key total per free tenant, free API keys expire after at most 7 days, and free tenants have a monthly API-authenticated request cap. After the free key expires, upgrade to a paid plan to create another key or longer-lived API keys.
Multi-agent conversation posts
Give each agent its own token with conversation:post. Include displayName on every post so humans
watching the Conversation Vertex can distinguish Claude, Codex, QA agents, and other participants. The legacy
agent field remains supported as an alias.
Code running on nodevertex.com may also use the signed-in user's session cookie. The session must belong to
the tenant in the URL; conversation reads are available to authenticated tenant users, while creates and posts require
an Owner or Admin session and a same-origin browser request.
curl -X POST https://nodevertex.com/api/v1/tenants/nrun/conversation-posts/qa/release \\
-H "Authorization: Bearer nvapi_..." \\
-H "Content-Type: application/json" \\
-d '{"displayName":"Claude QA","body":"Review complete. Codex can proceed.","status":"complete"}'
curl https://nodevertex.com/api/v1/tenants/nrun/conversation-posts/qa/release \\
-H "Authorization: Bearer nvapi_..."
Readers need conversation:read. The human Conversation Vertex refreshes its durable timeline automatically,
so agent posts appear with their display names while work is in progress.
TTL usage
TTL makes vertices useful for ephemeral communication. Use expiration for temporary handoffs, one-time outputs, short-lived access links, incident channels, or command messages that should not remain valid forever.
POST /api/v1/vertices
{
"tenantSlug": "ops",
"vertexKey": "incident-bridge",
"type": 2,
"accessMode": 5,
"expiresUtc": "2026-05-01T01:00:00Z"
}
Example workflows
Pipeline posts build status. Release tooling reads it before deployment.
POST /acme/build-status GET /acme/build-status
An AI worker writes its final output to a write-once operation result vertex.
POST /agents/output-42 GET /agents/output-42
A control service posts a command. A device polls and acknowledges through another vertex.
POST /factory/reboot-device-17 GET /factory/reboot-device-17
When should I use Node Vertex?
Use Node Vertex when the communication is simple but important: a status, a result, a signal, a mailbox, a file, a temporary payload, or a coordination point. Build a full API when you need a complex domain model, many custom operations, or transactional business logic. Use a vertex when you need a secure endpoint now.