Skip to main content
When the node library doesn’t have what you need, you write it. A node is a folder of YAML: you describe the service you want to call, and the platform performs it. There is nothing to compile and no package to install. You write the files, run the node against the real API, then publish it.

Before you begin

The platform is running (unoverse start). You’ve built the workflow from Create Your First Agent; you’ll extend it to test your node. Here is the node you are about to build, as Canvas will draw it:
My custom node
Quote
Ready
The bold line is this node’s name on your canvas, and you can rename it to whatever the step is doing. The line beneath it is the node type, Quote, which never changes. The colour and the type come from the files below. So do the handles: one on the left for the input, one on the right per output. Hover a handle and its connector name appears.

Build it

Four small files, and none of them is code.
What a node cannot do
  • It adds no code. The platform runs its own executor, the same one for every node.
  • It reaches only declared hosts. Anything else is refused, and https only.
  • It carries no keys. Yours stay in Canvas, supplied as it runs.
  • It is sealed. A stored copy that changed is refused at load.
Anatomy of a Node covers each of those in full.
1

Create the package

A package holds one or more nodes and declares which hosts they may call. In your Studio project workspace, create nodes/quote/ with one file in it:
package.yaml
allowedHosts is the list of hosts this package may reach, and everything else is refused. A node cannot call anywhere you have not named here.
2

Describe the node

Create quote/nodes/Quote/node.yaml. This one file says what the node is, what it connects to, and how to test it.
nodes/Quote/node.yaml
Each entry in outputs becomes a connector on the node. Downstream nodes read them as signal.quote1.quote and signal.quote1.author, where quote1 is the id Canvas gives the node when you drag it in.A bigger node splits interface and test into their own files. This one is small, so they stay here.
whenToUse decides whether the AI workflow builder can find your node at all. The catalog ranks it against the task being built, so lead with the outcome in plain words and keep it to one or two sentences. Describe what disqualifies your node as a property (β€œno settings to fill in”), and never name another node. The full guide is Node Discoverability; read it before writing this field for a real node.
3

Describe the call

Create quote/nodes/Quote/api/run.yaml. It lists the calls the node makes, and this node makes one.
nodes/Quote/api/run.yaml
It is a list even with one call, because a node often needs two: fetch a record, then fetch something the first reply pointed at. Naming each one is how a later call reads an earlier reply.transport: json says the reply arrives as one body. A streaming service uses transport: sse instead, and the node emits as tokens arrive.
4

Describe what comes out

Create quote/nodes/Quote/api/events.yaml. One row per output connector, in the order the node declares them.
nodes/Quote/api/events.yaml
This API returns an array with one object in it, so response[0].q is the quote text. Read this file and you know everything the node emits, without opening another one.
5

Check it

Check the node
Every message names the rule it broke and the page that explains it. Leave out the fixture above and it tells you so, rather than letting you find out later in a workflow.
6

Run it against the real API

Run the node
The platform doesn’t need to be running for this. It is your node, your machine, the real API.
7

Use it in a workflow

Deploy the node, and Quote is in the node library in Canvas.Open your workflow from Create Your First Agent, drag Quote in, and connect Input Trigger to it.Step through the workflow. Quote’s Debug tab shows a fresh quote from the API.Now feed it to the model: reference signal.quote1.quote in the OpenAI Stream prompt, and your Agent opens its answer with a famous quote.

When a node needs a key

Quote needs no key. Most services do, and the key never goes in these files. A node declares what it needs, by name:
nodes/YourNode/node.yaml
Then the request uses it:
nodes/YourNode/api/run.yaml
You enter the key once in Canvas, under Credentials. The platform encrypts it, and supplies it to the node at the moment it runs. The value is never in your files, never in git, and never in the node you hand to someone else. A node carries no keys, so sharing one never shares a secret. Credentials covers the full pattern.

Sharing it

Your node runs from the files in your repo, which is all you need while you build. To give it to anyone else, you publish it from Studio. Publishing writes the node into a universe as a record: no build, no package, nothing to download. A node arrives pending, because it is the only thing you publish that holds a URL and a key. Whoever runs the universe sees the hosts it wants to call and the credentials it needs, and accepting it makes it live. After that you publish freely, and it only pauses again if the node reaches for something new.
Publishing from Studio is not available yet. Until it is, a node lives in the repo it was written in.

Have Claude Code build it

Claude Code skill Β· ships with your repo
/unoverse-create
Claude Code already knows everything on this page. Open your repo in Claude Code and describe the node you want:
Create a node that fetches the top story from a news API.
The skill writes the files, adds the host to allowedHosts, checks it, and runs it against the real API.Not sure everything is wired up? Type /mcp in Claude Code: the unoverse-builder server should show as connected.
Using a different AI assistant? Point it at the node reference in your repo at docs/nodes/. It is the same material as the Nodes tab of these docs.

Next steps

Ingest content to Spatial

Ground your Agent’s answers in your own content.

Components and templates

Design the interfaces your Agents speak through.