SocialluxSociallux
Toggle navigation menu
Docs navigationv

Docs

Verbs API

Manage and execute verbs using a stable REST API. Create verb definitions, list your verbs, and execute automation workflows with full trace capture and audit logging.

Endpoints

All verb operations require an authenticated session or public access. Responses carry full metadata and traces for debugging.

POST/verbsauth: required

Create verb

Create a new verb definition with name, type, and action/step configuration.

Request body

{
  "name": "My custom verb",
  "data": {
    "type": "primitive",
    "action": "atom.create",
    "params": {
      "data": "$input.data",
      "lexemeIds": "$input.lexemeIds"
    }
  },
  "isPublic": false
}

Success response (201)

{
  "_id": "507f1f77bcf86cd799439011",
  "owner": "507f1f77bcf86cd799439001",
  "name": "My custom verb",
  "data": {
    "type": "primitive",
    "action": "atom.create",
    "params": {
      "data": "$input.data",
      "lexemeIds": "$input.lexemeIds"
    }
  },
  "isPublic": false,
  "isSystem": false,
  "version": 1,
  "created": "2026-05-13T..."
}
GET/verbsauth: optional

List verbs

Retrieve verbs owned by or shared with the current user. Filters include scope, search, and pagination.

Query parameters

  • scope Filter by "own" (default) or "all" (includes public)
  • limit Max results (default 20, max 100)
  • skip Pagination offset (default 0)
  • search Filter verbs by name substring (case-insensitive, optional)
GET/verbs/:idauth: optional

Get verb

Retrieve a single verb by id. User must own, have share access, or verb must be public.

GET/verbs/:id/contractauth: optional

Get verb contract

Fetch a verb's declared contract (declaration, action, primitive, inputs, outputs, steps). Available as a primitive: verb.contract.

PUT/verbs/:idauth: required

Update verb

Modify a verb definition. Only owner or users with editor share access can update.

DELETE/verbs/:idauth: required

Delete verb (soft-delete)

Soft-delete a verb. Only owner or admin can delete. Deleted verbs are hidden from normal reads.

POST/verbs/:id/executeauth: optional

Execute verb

Run a verb—primitive or composed—with request input. Returns execution trace and output.

Request body

{
  "input": {
    "data": {
      "title": {
        "value": "Example"
      }
    },
    "lexemeIds": [
      "507f1f77bcf86cd799439021"
    ]
  }
}

Success response (200)

{
  "message": "Verb executed successfully",
  "execution": {
    "verbId": "507f...",
    "type": "primitive",
    "output": {
      "atom": {
        "id": "507f...",
        "version": 1,
        "lexemeIds": [
          "507f..."
        ],
        "data": {
          "title": {
            "value": "Example"
          }
        }
      }
    },
    "trace": [
      {
        "step": 0,
        "action": "atom.create",
        "status": "success",
        "output": {
          "atom": {
            "id": "507f...",
            "version": 1,
            "lexemeIds": [
              "507f..."
            ],
            "data": {
              "title": {
                "value": "Example"
              }
            }
          }
        }
      }
    ]
  }
}

Executing verbs

POST /verbs/:id/execute is the primary way to run verbs. The endpoint accepts input, resolves dynamic parameters, and returns a full execution trace.

Quickstart

Use contract introspection first, then execute with a typed input payload, then read execution.output from the response.

1. Inspect the contract

curl -X GET "https://api.sociallux.io//verbs/507f1f77bcf86cd799439011/contract" \
  -H "Content-Type: application/json"

2. Execute with runtime input

curl -X POST "https://api.sociallux.io//verbs/507f1f77bcf86cd799439011/execute" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "title": "Hello",
      "count": 1
    }
  }'

3. Read execution output

curl -X POST "https://api.sociallux.io//verbs/507f1f77bcf86cd799439011/execute" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "title": "Hello",
      "count": 1
    }
  }'

# Response excerpt
{
  "message": "Verb executed successfully",
  "execution": {
    "output": {
      "atom": {
        "id": "507f..."
      }
    }
  }
}

Execution request anatomy

POST /api/verbs/:id/execute
Content-Type: application/json

{
  "input": {
    // Any keys you want available to the verb.
    // Primitive verbs can reference these as $input.key.
    // Composed verbs can use them in step parameters.
    "data": { "title": { "value": "..." } },
    "lexemeIds": ["507f..."],
    "customField": "..."
  }
}

Primitive verb execution

Merges verb.data.params with request input. Missing fields in input are filled from params if defined.

Composed verb execution

Executes steps in order. Each step can use $input.*, $steps.N.output.*, and $last.output.* tokens.

Trace always returned

Even on failure, the trace array shows which steps succeeded and where execution stopped.

Contract introspection

GET /verbs/:id/contract returns the output of buildVerbContract(verb, getPrimitiveMetadataById): declaration, action, primitive, inputs, outputs, and steps (for composed verbs). The same contract plus HTTP usage enrichment is also available via the verb.contract primitive when called through the verb executor.

{
  "verb": {
    "id": "507f...",
    "name": "Create person",
    "version": 1,
    "type": "primitive"
  },
  "contract": {
    "declaration": "shapeA",
    "action": "atom.create",
    "primitive": {
      "id": "atom.create",
      "version": "1.0.0",
      "description": "..."
    },
    "inputs": {
      "data": {
        "source": "runtime",
        "required": true,
        "description": "...",
        "primitiveType": "object"
      }
    },
    "outputs": {
      "atom": {
        "type": "object",
        "description": "..."
      }
    },
    "steps": []
  }
}

Alternative: via the verb executor

Provision (or look up) a verb whose action is verb.contract and execute it with the target verbId as runtime input. The response includes a third usage block describing how to call that verb over HTTP.

curl -X POST "https://api.sociallux.io//verbs/<verbContractVerbId>/execute" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "verbId": "507f1f77bcf86cd799439011"
    }
  }'

# Response excerpt (execution.output)
{
  "verb": {
    "id": "507f...",
    "name": "Create person",
    "description": "...",
    "type": "primitive",
    "owner": {
      "userId": "...",
      "organizationAtomId": null
    },
    "isPublic": false
  },
  "contract": { /* same as GET /verbs/:id/contract */ },
  "usage": {
    "method": "POST",
    "path": "/verbs/507f.../execute",
    "bodyShape": {
      "input": {
        "data": {
          "type": "object",
          "required": true,
          "description": "..."
        }
      }
    },
    "exampleRequest": {
      "method": "POST",
      "url": "/verbs/507f.../execute",
      "headers": { "Content-Type": "application/json" },
      "body": { "input": { "data": {} } }
    },
    "exampleResponse": {
      "message": "Verb executed successfully",
      "execution": {
        "verbId": "507f...",
        "type": "primitive",
        "output": { "atom": {} },
        "trace": [
          { "step": 0, "action": "<action>", "status": "success", "output": { "atom": {} } }
        ]
      }
    }
  }
}

Error responses

Errors are returned with a descriptive message and (where possible) a partial trace showing which steps succeeded before failure.

Contract introspection error codes

CodeHTTPMeaning
UNAUTHORIZED401Anonymous caller attempted to read a non-public verb.
INVALID_OBJECT_ID400The supplied verbId is missing or malformed.
VERB_NOT_FOUND404No matching verb exists or the verb is soft-deleted.
FORBIDDEN403Caller is authenticated but lacks read access.
404

Verb not found

No verb with the given id, or verb is deleted.

403

Permission denied

User cannot execute this verb (not owner, not in sharedWith, not public, or protected system verb).

400

Bad request

Verb definition is malformed (primitive missing action, composed with no steps, or input not an object).

500

Step execution failure

One of the action primitives failed. Partial trace shows which step failed and why.

Example error response

HTTP 500
{
  "error": "Lexeme not found",
  "trace": [
    {
      "step": 0,
      "action": "atom.create",
      "status": "success",
      "output": {
        "atom": {
          "id": "507f33...",
          "version": 1
        }
      }
    },
    {
      "step": 1,
      "action": "atom.assignLexeme",
      "status": "failed",
      "error": "Lexeme not found"
    }
  ]
}

Dynamic parameter mapping

In composed verbs, step parameters can use special token syntax to reference request input and prior step outputs.

$input.path

Reads from the request input object.

$input.lexemeIds → ["507f..."]

$steps.N.output.path

Reads from a specific step's output by index.

$steps.0.output.atom.id → "507f33..."

$last.output.path

Reads from the most recently executed step. Useful when you don't track indices.

$last.output.atom.id → "507f33..."

Authentication & Authorization

Verb operations follow Sociallux ownership rules. See the Verbs overview for full access model details.

Owner

Can read, update, share, and delete their verbs.

Editor (share access)

Can read and update the shared verb. Cannot delete or re-share.

Reader (share access)

Can read and execute the verb. Cannot update.

Public verbs

Any authenticated or anonymous user can read and execute. Owner still controls updates/deletion.

Usage example

Complete workflow: create a verb, then execute it with different inputs.

// 1. Create a verb that creates and classifies atoms
const verbResponse = await fetch("${BASE}/verbs", {
  method: "POST",
  credentials: "include",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "Create blog post",
    data: {
      type: "composed",
      steps: [
        {
          action: "atom.create",
          params: {
            data: "$input.data",
            isPublic: "$input.isPublic"
          }
        },
        {
          action: "atom.assignLexeme",
          params: {
            atomId: "$steps.0.output.atom.id",
            lexemeId: "$input.blogLexemeId"
          }
        }
      ]
    }
  })
});

const { _id: verbId } = await verbResponse.json();

// 2. Execute the verb multiple times with different inputs
const postData = {
  title: { value: "Getting Started with Verbs" },
  content: { value: "..." },
  published: true
};

const execResponse = await fetch(
  `${BASE}/verbs/${verbId}/execute`,
  {
    method: "POST",
    credentials: "include",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      input: {
        data: postData,
        isPublic: true,
        blogLexemeId: "507f..."
      }
    })
  }
);

const { execution } = await execResponse.json();
const { atomId } = execution.output.atom.id;

Learn more

Explore deeper concepts and architecture.

Base URL: https://api.sociallux.io/