Narrative Protocol

Deployments

Create and manage deployments

Deployments API

Deployment routes are world-scoped.

Endpoints

List Deployments

GET /api/worlds/:worldAddress/deployments?page=1&limit=20

Create Deployment

POST /api/worlds/:worldAddress/deployments
Request Body
{
  "name": "Season 1",
  "description": "Runtime deployment",
  "mode": "upgradable",
  "aiModelId": "openai/gpt-oss-120b",
  "isLLMPublic": false,
  "payToAddress": "6Q2...wallet",
  "bindings": [
    {
      "event": "race_result",
      "eventVersion": 1,
      "targetChains": ["near-testnet"],
      "onchain": {
        "stateChanges": ["wins", "speed_rating"],
        "result": ["winner"]
      }
    }
  ],
  "sourceDeployment": "0x123...abc"
}
FieldTypeRequiredDescription
namestringYesDeployment name.
descriptionstringNoDescription.
modeenumNoupgradable or locked (default upgradable).
aiModelIdstringNoSelected model ID.
isLLMPublicbooleanNoWhether LLM prompt/response data is public.
payToAddressstringNoPayment receiver Solana address for paid public execution.
bindingsobject[]YesInitial event bindings (array).
bindings[].eventstringYesEvent name.
bindings[].eventVersionnumberYesRelative version number.
bindings[].targetChainsenum[]NoChain networks for on-chain push (per binding).
bindings[].onchainobjectNoField filter for on-chain push (per binding).
bindings[].onchain.stateChangesstring[]NoAllowed state-change keys.
bindings[].onchain.resultstring[]NoAllowed result keys.
sourceDeploymentstringNoClone entity state and bindings from source deployment (address).

Get Deployment

GET /api/worlds/:worldAddress/deployments/:address

Update Deployment

PUT /api/worlds/:worldAddress/deployments/:address
Request Body
{
  "name": "Season 1 Updated",
  "description": "Updated description",
  "aiModelId": "openai/gpt-oss-120b",
  "isLLMPublic": true,
  "payToAddress": "6Q2...wallet"
}
FieldTypeRequiredDescription
namestringNoDeployment name.
descriptionstringNoDescription.
aiModelIdstringNoSelected model ID. Set to null to remove.
isLLMPublicbooleanNoWhether LLM prompt/response data is public.
payToAddressstringNoPayment receiver Solana address. Set to null to remove.

Delete Deployment

DELETE /api/worlds/:worldAddress/deployments/:address

Execute Event

POST /api/worlds/:worldAddress/deployments/:address/execute
Request Body
{
  "event": "race_result",
  "input": { "raceId": "RACE_001" }
}
FieldTypeRequiredDescription
eventstringYesEvent name to execute.
inputobjectNoEvent input payload.

Lock Deployment

POST /api/worlds/:worldAddress/deployments/:address/lock

Publish Deployment

POST /api/worlds/:worldAddress/deployments/:address/publish

Makes the deployment public, enabling public execution. This endpoint is idempotent — calling it on an already public deployment returns success.

Response:

{
  "success": true,
  "data": { "isPublic": true },
  "message": "Deployment published successfully"
}

Or if already public:

{
  "success": true,
  "data": { "isPublic": true },
  "message": "Deployment is already public"
}

List Event History

GET /api/worlds/:worldAddress/deployments/:address/history?page=1&limit=10

List Event Bindings

GET /api/worlds/:worldAddress/deployments/:address/event-bindings

Get Event Binding

GET /api/worlds/:worldAddress/deployments/:address/event-bindings?event=race_result

Query parameters:

  • event - Event name (required)

Create Event Bindings

POST /api/worlds/:worldAddress/deployments/:address/event-bindings
Request Body
[
  {
    "event": "race_result",
    "eventVersion": 2
  }
]
FieldTypeRequiredDescription
eventstringYesEvent name to bind.
eventVersionnumberYesRelative version number to bind.

Request body must be an array. Duplicate events are rejected.

Update Event Bindings

PUT /api/worlds/:worldAddress/deployments/:address/event-bindings
Request Body
[
  {
    "event": "race_result",
    "eventVersion": 3,
    "targetChains": ["solana-devnet"],
    "onchain": {
      "stateChanges": ["wins"],
      "result": ["winner"]
    }
  }
]
FieldTypeRequiredDescription
eventstringYesEvent name to update.
eventVersionnumberNoNew version number to bind.
targetChainsenum[]NoChain networks for on-chain push.
onchainobjectNoField filter for on-chain push.
onchain.stateChangesstring[]NoAllowed state-change keys.
onchain.resultstring[]NoAllowed result keys.

Request body must be an array. Duplicate events are rejected.

Delete Event Binding

DELETE /api/worlds/:worldAddress/deployments/:address/event-bindings?event=race_result

Query parameters:

  • event - Event name to unbind (required)

List Entity Instances

GET /api/worlds/:worldAddress/deployments/:address/entity-instances?page=1&limit=20

Create Entity Instance

POST /api/worlds/:worldAddress/deployments/:address/entity-instances
Request Body
{
  "entitySchema": "horse",
  "instanceId": "HORSE_1",
  "state": {
    "name": "Midnight Comet",
    "speed_rating": 0.85
  }
}
FieldTypeRequiredDescription
entitySchemastringYesEntity schema name.
instanceIdstringYesUnique per deployment+schema.
stateobjectNoInitial state. Defaults to {}.

Public Execution

Public execution is available via app route:

POST /app/deployments/:address/execute
Request Body
{
  "event": "race_result",
  "input": { "raceId": "RACE_001" },
  "wallet": "<solana-wallet>",
  "signature": "<base58-signature>",
  "message": "narrativeprotocol:<deploymentAddress>:<eventName>:<timestamp>"
}
FieldTypeRequiredDescription
eventstringYesEvent name to execute.
inputobjectNoEvent input payload.
walletstringYesSigner wallet (base58 public key).
signaturestringYesSignature over message.
messagestringYesnarrativeprotocol:{deploymentAddress}:{eventName}:{timestamp}.

Rules:

  • Event must allow public execution.
  • If executionSettings.priceUsd > 0, provide valid X-Payment header (x402).