Quickstart
Get started with Narrative Protocol in 5 minutes
Quickstart
This guide walks through creating a world, defining schemas and events, running a deployment, and executing an event.
Prerequisites
Set your base API URL to https://api.narrativeprotocol.com.
Getting an API key
Before making API calls, create an API key in https://studio.narrativeprotocol.com. You will use this key in the Authorization header for all /api/* requests.
Blueprint Layer
The Blueprint layer is where you define your world structure. This includes creating worlds, entity schemas with attributes, and events with versioned behavior. These definitions are separate from runtime execution.
Step 1: Create your world
A world is the top-level container for your simulation. It holds entities, events, and can have multiple deployments. The promptSeed helps the AI understand your world context.
curl -X POST https://api.narrativeprotocol.com/api/worlds \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token>" \
-d '{
"name": "Horse Racing",
"description": "A horse racing simulation world",
"domainTags": ["sports", "simulation"],
"promptSeed": "This world simulates realistic horse racing events."
}'const response = await fetch(`https://api.narrativeprotocol.com/api/worlds`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
body: JSON.stringify({
name: "Horse Racing",
description: "A horse racing simulation world",
domainTags: ["sports", "simulation"],
promptSeed: "This world simulates realistic horse racing events."
})
});
console.log(await response.json());import requests
response = requests.post(
"https://api.narrativeprotocol.com/api/worlds",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
json={
"name": "Horse Racing",
"description": "A horse racing simulation world",
"domainTags": ["sports", "simulation"],
"promptSeed": "This world simulates realistic horse racing events."
}
)
print(response.json())Response
{
"success": true,
"data": {
"id": 39,
"address": "0xd36f777a077ff3825653f6d521f1437b4da69699",
"userId": 746631,
"name": "Horse Racing",
"description": "A horse racing simulation world",
"domainTags": ["sports", "simulation"],
"promptSeed": "This world simulates realistic horse racing events.",
"isPublic": false,
"createdAt": "2026-02-18T04:13:02.315Z",
"updatedAt": "2026-02-18T04:13:02.315Z"
}
}Step 2: Define an entity schema
An Entity Schema defines the structure for entities in your world. For example, a "horse" schema defines what attributes (name, speed, wins) all horses will have. You can define attributes during entity schema creation, including type, constraints, and defaultValue.
Attribute type values:
stringintegerfloatbooleanjson
Attribute constraints fields:
min(number)max(number)enum(string array)
curl -X POST https://api.narrativeprotocol.com/api/worlds/<world-address>/entity-schemas \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token>" \
-d '{
"name": "horse",
"description": "A racing horse",
"attributes": [
{
"name": "speed_rating",
"type": "float",
"constraints": { "min": 0, "max": 1 },
"defaultValue": 0.5
},
{
"name": "wins",
"type": "integer",
"constraints": { "min": 0 },
"defaultValue": 0
}
]
}'const response = await fetch(`https://api.narrativeprotocol.com/api/worlds/<world-address>/entity-schemas`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
body: JSON.stringify({
name: "horse",
description: "A racing horse",
attributes: [
{
name: "speed_rating",
type: "float",
constraints: { min: 0, max: 1 },
defaultValue: 0.5
},
{
name: "wins",
type: "integer",
constraints: { min: 0 },
defaultValue: 0
}
]
})
});
console.log(await response.json());import requests
response = requests.post(
"https://api.narrativeprotocol.com/api/worlds/<world-address>/entity-schemas",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
json={
"name": "horse",
"description": "A racing horse",
"attributes": [
{
"name": "speed_rating",
"type": "float",
"constraints": { "min": 0, "max": 1 },
"defaultValue": 0.5
},
{
"name": "wins",
"type": "integer",
"constraints": { "min": 0 },
"defaultValue": 0
}
]
}
)
print(response.json())Response
{
"success": true,
"data": {
"id": 53,
"worldId": 39,
"name": "horse",
"description": "A racing horse",
"createdAt": "2026-02-18T04:13:49.117Z",
"updatedAt": "2026-02-18T04:13:49.117Z",
"attributes": [
{
"name": "speed_rating",
"type": "float",
"constraints": { "min": 0, "max": 1 },
"defaultValue": 0.5
},
{
"name": "wins",
"type": "integer",
"constraints": { "min": 0 },
"defaultValue": 0
}
]
}
}Step 3: Create an event
Events define what can happen in your world.
firstVersion fields:
inputSchema: Defines the input payload expected at execution time.readEntities: Lists entity schemas the event can read.stateChangeSchema: Per-schema mutation mode (partial,full,append).partialmerges into existing state,fullreplaces state, andappendappends to arrays.outputSchema: Defines the expected public result fields.mutationSettings: Execution mode config (aiordirect;directuses a template). Whenmodeisai,behaviorPromptis required. Whenmodeisdirect,templateis required.executionSettings: Execution visibility and triggers (admin,public,cron) with optionalpriceUsdandcronconfig.
For more details, see Events.
curl -X POST https://api.narrativeprotocol.com/api/worlds/<world-address>/events \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token>" \
-d '{
"name": "race_result",
"description": "Resolves a race and updates horse stats",
"firstVersion": {
"inputSchema": { "raceId": "string" },
"readEntities": [{ "schema": "horse" }],
"stateChangeSchema": { "horse": "partial" },
"outputSchema": { "winner": "string", "time": "string" },
"mutationSettings": {
"mode": "ai",
"behaviorPrompt": "Determine the race winner based on horse speed ratings. Update the winner's wins count."
}
}
}'const response = await fetch(`https://api.narrativeprotocol.com/api/worlds/<world-address>/events`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
body: JSON.stringify({
name: "race_result",
description: "Resolves a race and updates horse stats",
firstVersion: {
inputSchema: { raceId: "string" },
readEntities: [{ schema: "horse" }],
stateChangeSchema: { horse: "partial" },
outputSchema: { winner: "string", time: "string" },
mutationSettings: {
mode: "ai",
behaviorPrompt: "Determine the race winner based on horse speed ratings. Update the winner's wins count."
}
}
})
});
console.log(await response.json());import requests
response = requests.post(
"https://api.narrativeprotocol.com/api/worlds/<world-address>/events",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
json={
"name": "race_result",
"description": "Resolves a race and updates horse stats",
"firstVersion": {
"inputSchema": { "raceId": "string" },
"readEntities": [{ "schema": "horse" }],
"stateChangeSchema": { "horse": "partial" },
"outputSchema": { "winner": "string", "time": "string" },
"mutationSettings": {
"mode": "ai",
"behaviorPrompt": "Determine the race winner based on horse speed ratings. Update the winner's wins count."
}
}
}
)
print(response.json())Live Layer
The Live layer is where your simulation actually runs. Deployments are isolated runtime instances of a world.
Step 4: Create a deployment
A deployment is a running instance of a world with its own isolated state.
curl -X POST https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token>" \
-d '{
"name": "Season 1",
"bindings": [{
"event": <event-name>,
"eventVersion": <event-version>,
"targetChains": ["near-testnet"]
}]
}'const response = await fetch(`https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
body: JSON.stringify({
name: "Season 1",
bindings: [{
event: <event-name>,
eventVersion: <event-version>,
targetChains: ["near-testnet"]
}]
})
});
console.log(await response.json());import requests
response = requests.post(
"https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
json={
"name": "Season 1",
"bindings": [{
"event": <event-name>,
"eventVersion": <event-version>,
"targetChains": ["near-testnet"]
}]
}
)
print(response.json())The targetChains option on each binding determines where event data for that event is stored on-chain:
[]- No on-chain storage (default)["solana-devnet"]- Push to Solana devnet["near-testnet"]- Push to NEAR testnet["solana-devnet", "near-testnet"]- Push to both chains
Step 5: Create entity instances
Entity instances are the actual data in your deployment.
curl -X POST https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments/<deployment-address>/entity-instances \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token>" \
-d '{
"entitySchema": "horse",
"instanceId": "HORSE_1",
"state": {
"name": "Midnight Comet",
"speed_rating": 0.85
}
}'const response = await fetch(`https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments/<deployment-address>/entity-instances`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
body: JSON.stringify({
entitySchema: "horse",
instanceId: "HORSE_1",
state: {
name: "Midnight Comet",
speed_rating: 0.85
}
})
});
console.log(await response.json());import requests
response = requests.post(
"https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments/<deployment-address>/entity-instances",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
json={
"entitySchema": "horse",
"instanceId": "HORSE_1",
"state": {
"name": "Midnight Comet",
"speed_rating": 0.85
}
}
)
print(response.json())Step 6: Execute an event
Executing an event triggers the AI engine and applies state changes to your deployment.
curl -X POST https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments/<deployment-address>/execute \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token>" \
-d '{
"event": <event-name>,
"input": { "raceId": "RACE_001" }
}'const response = await fetch(`https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments/<deployment-address>/execute`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
body: JSON.stringify({
event: <event-name>,
input: { raceId: "RACE_001" }
})
});
console.log(await response.json());import requests
response = requests.post(
f"https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments/<deployment-address>/execute",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer <your-token>"
},
json={
"event": <event-name>,
"input": { "raceId": "RACE_001" }
}
)
print(response.json())Response
{
"success": true,
"data": {
"historyId": 11133,
"eventVersion": 1,
"stateChanges": {
"horse:HORSE_1": {
"wins": 1
}
},
"result": {
"time": "2026-02-18T00:00:00Z",
"winner": "Midnight Comet"
},
"attestation": {
"signature": "0x0b09aa672cde45034a1091532b1e7f7e31b476181fd06ca4faafc566245a823f3ff0e8a65afd102b64a1370170e5819f242480e727d449cbdcc338d7324b9a191c",
"signing_address": "0xbBC409e6b529817D257aD61D5738D8e3a39b5791",
"signing_algo": "ecdsa",
"text": "d3fc5ada116a1c0c9359ea6b7297b210cfecd393facc04c5d20209002a2dd126:ad558a6182aa4c55374cbd5eae218d6b2dae1957780630ecc6a0f01e49214af9"
},
"oracle": {
"solana": null,
"near": {
"txHash": "8LjP9sqX26oQgScPy5RGzs8dEzwZiNSQHKrTpCLrP5yy",
"receiptId": "ZWsNXEXPp1KyQWB68psjypi1PHGjMC8MrAomHBQLpGr"
}
}
}
}Step 7: View updated state
After executing an event, you can query the entity instances to see how the state has changed.
curl https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments/<deployment-address>/entity-instances \
-H "Authorization: Bearer <your-token>"const response = await fetch(`https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments/<deployment-address>/entity-instances`, {
headers: {
"Authorization": "Bearer <your-token>"
}
});
console.log(await response.json());import requests
response = requests.get(
f"https://api.narrativeprotocol.com/api/worlds/<world-address>/deployments/<deployment-address>/entity-instances",
headers={
"Authorization": "Bearer <your-token>"
}
)
print(response.json())Next Steps
- Learn about Core Concepts - Architecture, versioning, modes
- Explore AI Engine - How events are processed and model selection
- See On-chain Oracle - Multi-chain verification
- Check the API Reference - Complete endpoints