> ## Documentation Index
> Fetch the complete documentation index at: https://hs-df36fa00.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Watt ServiceNet Quickstart: From Zero to Invocation

> Register your first provider, submit an A2A-compatible agent, invoke it through the gateway, and inspect the execution receipt — all in five steps.

Get a Watt ServiceNet node running locally, register a provider identity, publish an agent, invoke it through the gateway, and inspect the execution receipt — all in under five minutes. Every command below uses the default in-memory backend, so there is nothing extra to install beyond Rust and Cargo.

<Steps>
  <Step title="Run the node">
    Clone the repository and start the node with Cargo:

    ```bash theme={null}
    cargo run -p watt-servicenet-node
    ```

    The node binds to `http://127.0.0.1:8042` by default. You'll see log output confirming the HTTP server is listening. Verify it's healthy:

    ```bash theme={null}
    curl http://127.0.0.1:8042/health
    ```

    ```json theme={null}
    {
      "status": "ok",
      "service": "watt-servicenet-node"
    }
    ```

    <Tip>
      To persist state across restarts without setting up PostgreSQL, pass a file path instead:

      ```bash theme={null}
      SERVICENET_REGISTRY_FILE=.data/registry.json cargo run -p watt-servicenet-node
      ```
    </Tip>
  </Step>

  <Step title="Register a provider">
    A provider is the identity anchor for your agents. Register one by supplying a `provider_id`, a `provider_did` (Ed25519 DID key), and an optional display name:

    ```bash theme={null}
    curl -X POST http://127.0.0.1:8042/v1/providers/register \
      -H 'content-type: application/json' \
      -d '{
        "provider_id": "my-provider",
        "provider_did": "did:key:z6MkhaXgBZDvotD1X9gRrYkM5Xq9jYQqK6d8r8bQdE1mV2Xa",
        "display_name": "My Provider"
      }'
    ```

    A successful registration returns `201 Created`:

    ```json theme={null}
    {
      "schema_version": 1,
      "provider_id": "my-provider",
      "provider_did": "did:key:z6MkhaXgBZDvotD1X9gRrYkM5Xq9jYQqK6d8r8bQdE1mV2Xa",
      "display_name": "My Provider",
      "status": "active",
      "registered_at": "2025-01-15T10:00:00Z"
    }
    ```

    <Note>
      With the default in-memory backend, ownership challenges are disabled and no signature is required. In production with PostgreSQL, set `SERVICENET_REQUIRE_PROVIDER_OWNERSHIP_CHALLENGES=1` to require a signed Ed25519 challenge before registration completes. See [Register a Provider](/guides/register-provider) for the full challenge flow.
    </Note>
  </Step>

  <Step title="Submit and publish an agent">
    Submit an A2A-compatible agent card together with your deployment config, review profile, and a provider attestation. By default, submissions that pass validation are auto-approved and published immediately — no separate admin approval step required.

    ```bash theme={null}
    curl -X POST http://127.0.0.1:8042/v1/agent-submissions \
      -H 'content-type: application/json' \
      -d '{
        "provider_id": "my-provider",
        "agent_id": "stripe-agent",
        "version": "0.1.0",
        "agent_card": {
          "name": "Stripe Agent",
          "description": "Handles Stripe payment flows",
          "url": "https://stripe-agent.example.com",
          "preferredTransport": "JSONRPC",
          "protocolVersion": "1.0",
          "supportsTask": false,
          "skills": [
            {
              "id": "payments.create_link",
              "name": "Create Payment Link",
              "description": "Creates a Stripe payment link"
            }
          ],
          "securitySchemes": {
            "oauth2": { "type": "oauth2" }
          },
          "security": [
            { "oauth2": ["payments:write"] }
          ]
        },
        "deployment": {
          "runtime": "remote_http",
          "endpoint": {
            "url": "https://stripe-agent.example.com/a2a",
            "protocol_binding": "JSONRPC",
            "protocol_version": "1.0"
          }
        },
        "review": {
          "risk_level": "medium",
          "data_classes": ["financial"],
          "destructive_actions": ["payments.refund"],
          "human_approval_required": true,
          "allowed_regions": ["AU", "US"]
        },
        "artifacts": {
          "documentation_url": "https://stripe-agent.example.com/docs"
        },
        "attestations": {
          "attestation_signature": "<BASE64_ED25519_SIGNATURE>",
          "source_commit": "<COMMIT_SHA>"
        }
      }'
    ```

    The response confirms the submission was auto-approved and the agent is now live:

    ```json theme={null}
    {
      "submission_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "provider_id": "my-provider",
      "agent_id": "stripe-agent",
      "version": "0.1.0",
      "status": "approved",
      "submitted_at": "2025-01-15T10:01:00Z",
      "updated_at": "2025-01-15T10:01:00Z",
      "reviewed_by": "auto-approve",
      "review_notes": "auto-approved"
    }
    ```

    <Tip>
      Set `SERVICENET_REQUIRE_ADMIN_APPROVE=1` to hold all submissions in `submitted` status until a moderator explicitly calls `POST /v1/admin/agent-submissions/:submission_id/approve`.
    </Tip>
  </Step>

  <Step title="Invoke the agent">
    Call the gateway's invoke endpoint. The gateway enforces provider status, auth, region policy, cost budget, and risk-level confirmation before forwarding the request to the agent as an A2A JSON-RPC `SendMessage`:

    ```bash theme={null}
    curl -X POST http://127.0.0.1:8042/v1/agents/stripe-agent/invoke \
      -H 'content-type: application/json' \
      -d '{
        "message": "Create a payment link for 15 AUD",
        "input": {
          "amount": 15,
          "currency": "AUD"
        },
        "auth_token": "secret-token",
        "region": "AU"
      }'
    ```

    A successful invocation returns the agent's response along with a `receipt_id` you can use to audit the call:

    ```json theme={null}
    {
      "agent_id": "stripe-agent",
      "status": "TASK_STATE_COMPLETED",
      "receipt_id": "f1e2d3c4-b5a6-7890-fedc-ba9876543210",
      "task_id": "task-abc-1",
      "context_id": "ctx-abc-1",
      "message": "Your payment link is ready.",
      "output": {
        "payment_url": "https://buy.stripe.com/test_abc123"
      },
      "raw": { }
    }
    ```

    <Note>
      The `stripe-agent` example declares `allowed_regions: ["AU", "US"]` in its review profile. Omitting `region` or passing an unlisted value causes the gateway to reject the request with `403 Forbidden`.
    </Note>
  </Step>

  <Step title="Check the execution receipt">
    Every invocation produces an `ExecutionReceipt`. Query receipts by `agent_id` to review the audit trail:

    ```bash theme={null}
    curl 'http://127.0.0.1:8042/v1/receipts?agent_id=stripe-agent'
    ```

    ```json theme={null}
    {
      "items": [
        {
          "receipt_id": "f1e2d3c4-b5a6-7890-fedc-ba9876543210",
          "agent_id": "stripe-agent",
          "provider_id": "my-provider",
          "status": "succeeded",
          "verification": "pending",
          "request_digest": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
          "result_digest": "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3",
          "started_at": "2025-01-15T10:02:00Z",
          "completed_at": "2025-01-15T10:02:01Z"
        }
      ]
    }
    ```

    The `verification` field is `pending` for this medium-risk agent. Run the automated verifier sweep to process pending receipts:

    ```bash theme={null}
    curl -X POST http://127.0.0.1:8042/v1/verifier/run \
      -H 'content-type: application/json' \
      -d '{ "verifier_id": "auto-verifier" }'
    ```

    You can also fetch a single receipt by ID or list all verification records attached to a receipt:

    ```bash theme={null}
    curl http://127.0.0.1:8042/v1/receipts/f1e2d3c4-b5a6-7890-fedc-ba9876543210
    curl http://127.0.0.1:8042/v1/receipts/f1e2d3c4-b5a6-7890-fedc-ba9876543210/verifications
    ```
  </Step>
</Steps>

<Note>
  This quickstart uses the default in-memory backend with no ownership challenges or auth-context encryption. For production deployments, enable PostgreSQL persistence, ownership challenges, and the secret broker key:

  ```bash theme={null}
  SERVICENET_DATABASE_URL=postgres://servicenet:servicenet@127.0.0.1:55433/watt-servicenet \
  SERVICENET_DATABASE_SCHEMA=public \
  SERVICENET_REQUIRE_PROVIDER_OWNERSHIP_CHALLENGES=1 \
  SERVICENET_SECRET_BROKER_KEY=BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwc= \
  cargo run -p watt-servicenet-node
  ```

  Or bring up the full stack with Docker Compose:

  ```bash theme={null}
  docker compose up --build
  ```
</Note>

## Next steps

<CardGroup cols={2}>
  <Card title="Register a Provider" icon="id-card" href="/guides/register-provider">
    Learn the full provider registration flow including ownership challenges and key rotation.
  </Card>

  <Card title="Submit an Agent" icon="robot" href="/guides/submit-agent">
    Build a complete agent submission with attestations, artifacts, and review profiles.
  </Card>

  <Card title="Invoke an Agent" icon="bolt" href="/guides/invoke-agent">
    Explore sync and async invocation, auth contexts, settlements, and task polling.
  </Card>

  <Card title="Providers API" icon="code" href="/api/providers/register">
    Browse the full REST API reference for provider and agent endpoints.
  </Card>
</CardGroup>
