WATP Docs

WATP Documentation

The Wortic Autonomous Trade Protocol is an open protocol for autonomous Agent-to-Agent (A2A) negotiations between enterprises. This guide covers installation, configuration, and SDK integration.

Preview Release

WATP is in internal seeding (Phase 1). The SDK is stable for integration within the Wortic ecosystem. APIs may change before the open-source release.

Quick Start

Deploy a local WATP node connected to the network in three commands.

bash
# 1. Clone the local node
git clone https://github.com/williamschonswortic/watp-node.git
cd watp-node

# 2. Configure the environment
cp .env.example .env
nano .env  # Set ERP_DSN, AI_PROVIDER, GUARDRAILS

# 3. Start the node
docker-compose up -d

Installation

Requirements

  • PHP 8.1+ (8.3 recommended)
  • Docker and Docker Compose
  • ERP access (MySQL / PostgreSQL / REST API)
  • AI key (optional — OpenAI, Anthropic, Google Gemini, or local Ollama)

Via Composer

bash
composer require wortic/watp-sdk

Via Docker

bash
docker pull ghcr.io/wortic/watp-node:latest
docker run -d \
  --name watp-node \
  -p 8090:8090 \
  -v $(pwd)/.env:/app/.env \
  ghcr.io/wortic/watp-node:latest

Message Format

All WATP communication uses a standardized JSON envelope. Each message references the previous hash, forming an immutable chain.

json
{
  "protocol": "watp/1.0",
  "id": "msg_01HZ3...",
  "type": "HASH_PROPOSAL",
  "timestamp": "2026-04-13T15:30:00Z",
  "from": {
    "agent": "agent://sales@company-a.watp",
    "tax_id": "12.345.678/0001-90"
  },
  "to": {
    "agent": "agent://procurement@company-b.watp",
    "tax_id": "98.765.432/0001-10"
  },
  "payload": {
    "items": [{ "description": "Cat6 Patch Cord 1.5m", "qty": 500, "unit_price": 4.20, "currency": "BRL" }],
    "payment_terms": "30/60/90",
    "delivery_days": 7
  },
  "prev_hash": "sha256:a1b2c3d4e5f6...",
  "hash": "sha256:f9e8d7c6b5a4...",
  "signature": "x509:RSA256:base64..."
}

State Machine

The lifecycle of a WATP negotiation follows deterministic states. Each transition is validated and persisted in the hash chain.

State Type Description
HASH_INTEREST Start Agent detects demand and publishes a buy interest to the network
HASH_PROPOSAL Negotiation Formal proposal: price, payment terms, delivery
HASH_COUNTER Negotiation Counter-proposal within configured guardrails
HASH_WAITING_HUMAN Safety Outside parameters — human approval required
HASH_CONCLUDED Final Agreement signed with X.509 certificates
HASH_CANCELLED Final Negotiation cancelled by either party

HASH_WAITING_HUMAN

This state is mandatory when the negotiation exceeds configured guardrails. The system never closes an agreement outside defined limits without explicit human approval.

Hash Chain

Each message contains the SHA-256 hash of the previous message, creating an immutable audit trail without requiring a blockchain.

php
use Wortic\WATP\HashChain;

$chain = new HashChain();
$hash = $chain->generate([
    'type'     => 'HASH_PROPOSAL',
    'from'     => 'agent://sales@my-company.watp',
    'payload'  => $payload,
    'prev_hash' => $previousHash,
]);
$isValid = $chain->validate($negotiationHistory);

X.509 Signatures

To guarantee non-repudiation with legal validity, the HASH_CONCLUDED state is signed with X.509 digital certificates from both enterprises.

php
use Wortic\WATP\Signer;

$signer = new Signer('/path/to/certificate.pfx', 'password');
$signed = $signer->sign($concludedMessage);
$valid  = $signer->verify($receivedMessage, $publicKey);

PHP SDK

The PHP SDK abstracts network communication, hash validation, and agent management.

php — initialization
<?php declare(strict_types: 1);

use Wortic\WATP\Node;
use Wortic\WATP\Config;
use Wortic\WATP\Agent\SalesAgent;
use Wortic\WATP\Agent\ProcurementAgent;

$config = Config::fromEnv(__DIR__ . '/.env');
$node   = new Node($config);
$node->register(new SalesAgent($config));
$node->register(new ProcurementAgent($config));
$node->listen();

Configuration

All configuration is file-based via .env in the node directory.

.env
# Identity
WATP_NODE_ID=my-company
WATP_TAX_ID=12.345.678/0001-90

# Legacy ERP connection
ERP_DSN=mysql://user:pass@localhost/erp_db

# AI Engine
AI_PROVIDER=openai          # openai | anthropic | gemini | ollama
AI_API_KEY=sk-...
AI_MODEL=gpt-4o-mini

# Guardrails
GUARD_MIN_MARGIN=15
GUARD_MAX_DISCOUNT=20
GUARD_MAX_PAYMENT_DAYS=90
GUARD_AUTO_APPROVE_BELOW=5000

# X.509 Certificate
CERT_PATH=/certs/company.pfx
CERT_PASSWORD=certificate-password

Agents

Agents are PHP classes encapsulating business logic. Extend the base agent.

php — custom agent
class MySalesAgent extends BaseAgent
{
    public function handleInterest(Message $msg): ?Message
    {
        $product = $this->erp->semanticSearch($msg->payload['description']);
        if (!$product) return null;

        $price = $this->calculatePrice($product, $msg->payload['qty'], Guardrails::fromConfig());
        return $this->propose($msg, [
            'item' => $product->name, 'qty' => $msg->payload['qty'],
            'unit_price' => $price, 'currency' => 'BRL',
        ]);
    }
}

Guardrails

Immutable business rules constraining AI negotiations. If exceeded, state transitions to HASH_WAITING_HUMAN.

Parameter Type Description
GUARD_MIN_MARGIN int (%) Minimum acceptable gross margin
GUARD_MAX_DISCOUNT int (%) Maximum discount over list price
GUARD_MAX_PAYMENT_DAYS int Maximum payment term in days
GUARD_AUTO_APPROVE_BELOW float Auto-approve below this total
GUARD_MAX_ROUNDS int Max counter-proposals before escalation
GUARD_BLOCKED_IDS string Comma-separated blocked tax IDs

Products

The Product class provides typed access to the partner catalog with 18 enriched fields including dimensions, cost price, NCM code, and lead time.

php — listing products
use Wortic\WATP\Client;
use Wortic\WATP\Product;

$client = new Client(['node_url' => 'https://site-a.wortic.com/api']);

// List all products (returns Product[])
$products = $client->listProducts();
foreach ($products as $p) {
    printf("%s — %s — R$ %.2f\n", $p->sku, $p->name, $p->price);
}

// Find a single product by SKU
$patch = $client->getProduct('PATCH-C6-1.5M');
if ($patch) {
    echo $patch->brand;       // "Furukawa"
    echo $patch->weightKg;    // 0.05
    echo $patch->leadTimeDays; // 3
}

Product Fields

Property Type Description
namestringProduct name
skustringUnique stock keeping unit
pricefloatList price
costPrice?floatCost price (margin calculation)
category?stringProduct category
ncmCode?stringNCM fiscal code (Brazil)
brand?stringManufacturer brand
weightKg?floatWeight in kilograms
minOrderQty?intMinimum order quantity
leadTimeDays?intDelivery lead time in days

API Endpoints

The local node exposes a REST API for integration with external systems.

POST
/api/v1/negotiate

Start a new negotiation by publishing HASH_INTEREST.

GET
/api/v1/negotiations

List all active negotiations with current status.

GET
/api/v1/negotiations/{id}

Full detail including the complete hash chain.

POST
/api/v1/negotiations/{id}/approve

Human approval for HASH_WAITING_HUMAN state.

POST
/api/v1/negotiations/{id}/cancel

Cancel a negotiation, generating HASH_CANCELLED.

GET
/api/v1/health

Node health: status, uptime, registered agents.

GET
/api/v1/catalog

Full product catalog with enriched fields (18 properties per product).

Webhooks

Configure webhooks to receive real-time events in your system.

json — webhook payload
{
  "event": "negotiation.concluded",
  "timestamp": "2026-04-13T15:45:00Z",
  "data": {
    "negotiation_id": "neg_01HZ3...",
    "total_value": 2100.00,
    "final_hash": "sha256:c4d5e6..."
  },
  "signature": "hmac-sha256:..."
}

Error Codes

Code Constant Description
4001 INVALID_HASH_CHAIN Previous hash does not match
4002 GUARDRAIL_VIOLATED Proposal exceeded guardrails
4003 INVALID_SIGNATURE X.509 signature invalid or expired
4004 AGENT_NOT_FOUND Destination agent not on network
4005 NEGOTIATION_EXPIRED Negotiation TTL expired
5001 ERP_CONNECTION_FAILED Could not connect to local ERP
5002 AI_PROVIDER_ERROR Error calling AI provider API

BYOK — Bring Your Own Key

Use your own API key. You control costs, model selection, and rate limits.

.env
AI_PROVIDER=openai
AI_API_KEY=sk-proj-...
AI_MODEL=gpt-4o-mini

Local Edge Compute

Zero cost. The model runs on the client's own server, fully offline and private.

.env
AI_PROVIDER=ollama
AI_OLLAMA_URL=http://localhost:11434
AI_MODEL=llama3.1:7b

Anti-Amnesia Orchestrator

Ensures the model never loses negotiation context or breaks JSON format. Automatically prunes history and re-injects the system prompt.

php
use Wortic\WATP\AI\Orchestrator;

$orchestrator = new Orchestrator([
    'max_context_tokens' => 4096,
    'prune_strategy'    => 'keep_last_3_turns',
    'force_json_output'  => true,
    'temperature'        => 0.1,
]);
$response = $orchestrator->complete($negotiationCtx, $currentMsg);

Why Anti-Amnesia?

In extended negotiations (5+ rounds), smaller models lose initial context. The Orchestrator maintains a compressed summary plus the intact system prompt, ensuring consistency even with limited context windows.