Docs

DCN Public API Documentation

REST API for the Decentralised Creative Network. This document covers the current dcn-server endpoints: /connector, /format, /transformation, /condition, and /execute.

Prototype / Pre-MVP Notice

DCN and this API are still experimental. Use them for preview and prototyping, not production-critical work. Behavior may change between releases.

Terminology note

The tutorial uses particles to describe flowing values. In the API, the main objects are connector, transformation, condition, format, account, and execute.

Base URL: https://api.decentralised.art/chain Version: GET /version

Identity & Actor Model

Authentication is wallet-based. Humans and AI agents both authenticate with an EVM address via nonce + signature, then use JWT Bearer tokens on protected endpoints.

{
  "identity_substrate": "evm_address",
  "login_method": "nonce + signature",
  "token": "Authorization: Bearer <access_token>",
  "protected_endpoints": [
    "POST /connector",
    "POST /transformation",
    "POST /condition",
    "POST /execute"
  ]
}

Standard Parameters

Address

  • 0x + 40 hex chars

Pagination

  • limit - required integer on /account and /format, max 256
  • Account cursors: after_connectors, after_transformations, after_conditions
  • Format cursor: after

Entity IDs

  • connector name - string
  • transformation name - string
  • condition name - string

Execution Payload

  • connector_name - string
  • particles_count - requested output count (examples below use a decimal string; max 65536)
  • dynamic_ri - object keyed by RI position with values {start_point, transformation_shift}

Standard Error Shape

Error responses use a common JSON structure:

{
  "message": "string"
}

Common status codes: 400, 401, 404, 500.

Authentication Flow

1) Request nonce, 2) sign message Login nonce: <nonce>, 3) exchange signature for JWT.

GET /nonce/{address}

Returns a one-time nonce for a wallet address.

curl -X GET "https://api.decentralised.art/chain/nonce/0x48f750696ed392ca6d449a3d214656d024c5756f"
{
  "nonce": "589298"
}

POST /auth

Verifies address/signature/message and returns JWT.

curl -X POST "https://api.decentralised.art/chain/auth" \
  -H "Content-Type: application/json" \
  -d '{
    "address": "0x48f750696ed392ca6d449a3d214656d024c5756f",
    "message": "Login nonce: 589298",
    "signature": "<hex_signature>"
  }'
{
  "access_token": "<jwt>"
}

The response also includes Authorization: Bearer <jwt> header.

Version

GET /version

curl -X GET "https://api.decentralised.art/chain/version"
{
  "version": "1.2.3",
  "build_timestamp": "2026-03-20T12:00:00Z"
}

Account

GET /accounts?limit={limit}[&after={token}]

Public endpoint. Returns a cursor-paginated list of unique owner accounts across published connectors, transformations, and conditions.

curl -X GET "https://api.decentralised.art/chain/accounts?limit=50"
{
  "limit": 50,
  "total_accounts": 3,
  "cursor": {
    "has_more": false,
    "next_after": null
  },
  "accounts": [
    "0x48f750696ed392ca6d449a3d214656d024c5756f",
    "0x7e5f4552091a69125d5dfcb7b8c2659029395bdf",
    "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"
  ]
}

GET /account/{address}?limit={limit}[&after_connectors= {token}][&after_transformations={token}][&after_conditions= {token}]

Public endpoint. Returns owned connector/transformation/condition names for an address using independent cursors.

curl -X GET "https://api.decentralised.art/chain/account/0x48f750696ed392ca6d449a3d214656d024c5756f?limit=200"
{
  "owned_connectors": ["c0", "c2", "c3"],
  "owned_transformations": ["add", "identity"],
  "owned_conditions": ["alwaystrue"],
  "address": "0x48f750696ed392ca6d449a3d214656d024c5756f",
  "limit": 200,
  "cursor_connectors": {
    "has_more": false,
    "next_after": null
  },
  "cursor_transformations": {
    "has_more": false,
    "next_after": null
  },
  "cursor_conditions": {
    "has_more": false,
    "next_after": null
  }
}

Format

GET /formats?limit={limit}[&after={token}]

Public endpoint. Returns a cursor-paginated list of all known format hashes.

curl -X GET "https://api.decentralised.art/chain/formats?limit=50"
{
  "limit": 50,
  "total_formats": 2,
  "cursor": {
    "has_more": false,
    "next_after": null
  },
  "formats": [
    "0x1b897f4f7102f2dc0ba6a907de264048ef7f4e5e8a4ebdd17d5ef2f4899f7fd2",
    "0x2d80434f16e3a95c3d27dcbf60f142f1fef4d0b6e77a6314c61a0e117ba53f2e"
  ]
}

GET /format/{format_hash}?limit={limit}[&after={ token}]

Public endpoint. Returns connector names and scalar labels for a format hash.

curl -X GET "https://api.decentralised.art/chain/format/0x1b897f4f7102f2dc0ba6a907de264048ef7f4e5e8a4ebdd17d5ef2f4899f7fd2?limit=200"
{
  "format_hash": "0x1b897f4f7102f2dc0ba6a907de264048ef7f4e5e8a4ebdd17d5ef2f4899f7fd2",
  "limit": 200,
  "total_connectors": 3,
  "cursor": {
    "has_more": false,
    "next_after": null
  },
  "scalars": ["pitch:0", "time:0", "durationv2:0", "velocity:0"],
  "connectors": ["chromatic_scale", "melody_core", "melody_alt"]
}

scalars here describe the output shape of the format. path values returned by /execute are runtime graph paths produced during execution.

Connectors

HEAD /connector/{name}

Checks if connector exists.

GET /connector/{name}

Returns the connector record by name.

curl -X GET "https://api.decentralised.art/chain/connector/chromatic_scale"
{
  "name": "chromatic_scale",
  "dimensions": [
    {
      "transformations": [{ "name": "add", "args": [1] }],
      "composite": "pitch",
      "bindings": {}
    },
    {
      "transformations": [{ "name": "add", "args": [1] }],
      "composite": "time",
      "bindings": {}
    }
  ],
  "condition_name": "",
  "condition_args": [],
  "static_ri": {},
  "owner": "0x48f750696ed392ca6d449a3d214656d024c5756f",
  "address": "0x0",
  "format_hash": "0x1b897f4f7102f2dc0ba6a907de264048ef7f4e5e8a4ebdd17d5ef2f4899f7fd2"
}

POST /connector

Protected endpoint. Creates/deploys connector.

curl -X POST "https://api.decentralised.art/chain/connector" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "chromatic_scale",
    "dimensions": [
      {
        "transformations": [{ "name": "add", "args": [1] }],
        "composite": "pitch",
        "bindings": {}
      },
      {
        "transformations": [{ "name": "add", "args": [1] }],
        "composite": "time",
        "bindings": {}
      },
      {
        "transformations": [{ "name": "identity", "args": [] }],
        "composite": "durationv2",
        "bindings": {}
      },
      {
        "transformations": [{ "name": "identity", "args": [] }],
        "composite": "velocity",
        "bindings": {}
      }
    ],
    "condition_name": "",
    "condition_args": []
  }'
{
  "name": "chromatic_scale",
  "owner": "0x48f750696ed392ca6d449a3d214656d024c5756f",
  "address": "0x0",
  "format_hash": "0x1b897f4f7102f2dc0ba6a907de264048ef7f4e5e8a4ebdd17d5ef2f4899f7fd2"
}

Connector payload shape example

Example with composites, bindings, conditions, and static_ri.

{
  "name": "host_with_defaults",
  "dimensions": [
    {
      "transformations": [{ "name": "math_add_v1", "args": [1] }],
      "composite": "child_connector",
      "bindings": { "0": "time" }
    },
    {
      "transformations": [{ "name": "util_identity_v1", "args": [] }],
      "bindings": {}
    }
  ],
  "condition_name": "logic_always_true_v1",
  "condition_args": [],
  "static_ri": {
    "0": {
      "start_point": 10,
      "transformation_shift": 0
    }
  }
}

Connector payload rules

  • dimensions is required and must contain at least one dimension.
  • For each dimension, transformations array is required.
  • bindings map is allowed only when that dimension has non-empty composite.
  • Each bindings key must be a canonical decimal slot id string (for example "0", "1") and each value must be a connector name. Bindings fill child open slots exposed by the connected child connector.
  • static_ri is optional. Its keys are canonical decimal DFS RI position strings and its values are {start_point, transformation_shift}.
  • Use only the connector-native fields shown above (composite, bindings, transformations, condition_name, condition_args, optional static_ri).

Transformations

sol_src must be only the Solidity function body for run(uint32 x, uint32[] calldata args). Do not include pragma, import, contract, or a full function declaration.

Deployment names are permanent. Use unique test_* names for experiments.

HEAD /transformation/{name}

Checks if transformation exists.

GET /transformation/{name}

curl -X GET "https://api.decentralised.art/chain/transformation/add"
{
  "name": "add",
  "sol_src": "return x + args[0];",
  "owner": "0x48f750696ed392ca6d449a3d214656d024c5756f",
  "address": "0x0"
}

POST /transformation

curl -X POST "https://api.decentralised.art/chain/transformation" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "add",
    "sol_src": "return x + args[0];"
  }'
{
  "name": "add",
  "owner": "0x48f750696ed392ca6d449a3d214656d024c5756f",
  "address": "0x0"
}

Conditions

sol_src must be only the Solidity function body for check(int32[] calldata args). Do not include pragma, import, contract, or a full function declaration.

Deployment names are permanent. Use unique test_* names for experiments.

HEAD /condition/{name}

Checks if condition exists.

GET /condition/{name}

curl -X GET "https://api.decentralised.art/chain/condition/alwaystrue"
{
  "name": "alwaystrue",
  "sol_src": "return true;",
  "owner": "0x48f750696ed392ca6d449a3d214656d024c5756f",
  "address": "0x0"
}

POST /condition

curl -X POST "https://api.decentralised.art/chain/condition" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "alwaystrue",
    "sol_src": "return true;"
  }'
{
  "name": "alwaystrue",
  "owner": "0x48f750696ed392ca6d449a3d214656d024c5756f",
  "address": "0x0"
}

Execution

Protected endpoint. Runs a connector through Runner and returns output streams.

POST /execute

curl -X POST "https://api.decentralised.art/chain/execute" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "connector_name": "chromatic_scale",
    "particles_count": "16",
    "dynamic_ri": {
      "0": {
        "start_point": 10,
        "transformation_shift": 0
      },
      "3": {
        "start_point": 1,
        "transformation_shift": 0
      }
    }
  }'
[
  { "path": "/chromatic_scale:0", "data": [60, 61, 62, 63] },
  { "path": "/chromatic_scale:1", "data": [0, 1, 2, 3] },
  { "path": "/chromatic_scale:2", "data": [1, 1, 1, 1] },
  { "path": "/chromatic_scale:3", "data": [100, 100, 100, 100] }
]

Server limit: particles_count <= 65536.

Response path values are scalar paths generated by Runner (connector name + dimension index chain), not scalar labels from /format.

Running Instances behavior

  • API field is dynamic_ri, keyed by DFS RI position ("0", "1", ...). Each entry contains start_point and transformation_shift.
  • Missing positions are treated as dynamic defaults: {start_point: 0, transformation_shift: 0}.
  • Static RI positions defined on-chain in static_ri are locked and must not be overridden by dynamic_ri.

Collections

DCN includes a Core Collection of reusable transformations and conditions.

Connector coverage is lighter and currently focused on templates, not a large canonical connector catalog.

CORS / OPTIONS

The server exposes OPTIONS for auth, account, connector, format, transformation, condition, and execute endpoints. Typical allowed headers include Authorization, Content-Type.

# examples
OPTIONS /auth
OPTIONS /account/{address}?limit={limit}&after_connectors={token}&after_transformations={token}&after_conditions={token}
OPTIONS /format/{format_hash}?limit={limit}&after={token}
OPTIONS /connector/{name}
OPTIONS /transformation/{name}
OPTIONS /condition/{name}
OPTIONS /execute

Roadmap

For upcoming API and protocol milestones, see Roadmap.