DEV Community

Nettrux
Nettrux

Posted on Originally published at nettrux.ai

How an AI agent discovers a 3PL over x402

How an AI agent discovers a 3PL over x402

Agent builders keep asking the same first question: where does my agent look?

Nettrux is the first 3PL on x402, so the answer is deliberately boring and HTTP-native. Before any quote, before any payment header, an agent should fetch three public documents:

  1. The discovery pointer at https://www.nettrux.ai/.well-known/x402
  2. The human/agent guide at https://www.nettrux.ai/agents
  3. The field contract at https://nettrux-edge.fly.dev/openapi.json

This article is a how-to. Every snippet below was run against the live URLs on Nov 9, 2026 (America/Los_Angeles). The outputs are real. The gates are still off — and we say that in the same breath as the discovery story.

What you will (and will not) get today

You will get: a machine-readable pointer, an agent guide, a 126-path OpenAPI for the freight API host, and a clear list of deploy gates.

You will not get: a live public pay-and-book endpoint, a populated resources array, public real-money settlement, or guest checkout. Those three switches are baked false:

  • EDGE_X402_DISCOVERY_PUBLISHED: false
  • X402_REAL_MONEY_SETTLEMENT_LIVE: false
  • GUEST_X402_CHECKOUT_ENABLED: false

Nettrux has settled a real x402 USDC payment on Base in testing. That is not the same as a public endpoint. Keep reading if you are wiring discovery into an agent today; stop if you expected a stranger wallet to book a truck without a human and a bearer token.

Step 1 — Fetch the discovery pointer

x402 discovery starts at /.well-known/x402 on the site an agent already trusts. On Nettrux that document is a pointer, not a payable catalog.

import json
import urllib.request

DISCOVERY = "https://www.nettrux.ai/.well-known/x402"

req = urllib.request.Request(
    DISCOVERY,
    headers={
        "User-Agent": "nettrux-discovery-howto/1.0",
        "Accept": "application/json",
    },
)
with urllib.request.urlopen(req, timeout=20) as r:
    doc = json.load(r)

print(doc["name"], doc["kind"], doc["x402Version"])
print("resourceHost:", doc["resourceHost"])
print("openapi:", doc["openapi"])
print("resources:", doc["resources"])
print("gates:", doc["gates"])
print("payment.claimed:", doc["payment"]["claimed"])
Enter fullscreen mode Exit fullscreen mode

Live output from that run:

Nettrux resource-server 1
resourceHost: https://nettrux-edge.fly.dev
openapi: https://nettrux-edge.fly.dev/openapi.json
resources: []
gates: {
  "EDGE_X402_DISCOVERY_PUBLISHED": false,
  "GUEST_X402_CHECKOUT_ENABLED": false,
  "X402_REAL_MONEY_SETTLEMENT_LIVE": false
}
payment.claimed: False
Enter fullscreen mode Exit fullscreen mode

Read that carefully:

  • resources is empty while discovery is unpublished.
  • payment.claimed is false — the pointer does not name an asset, a chain, or a payee.
  • resourceHost and openapi tell the agent where the freight API lives.
  • gates are the same three booleans as llms.txt and the agent guide.

The pointer also lists a helper array, x402Resources, that names the documented commit route on the freight API host. That entry is catalog metadata for builders. It is not a claim that the public rail settles money today:

for res in doc.get("x402Resources") or []:
    print(res["method"], res["url"])
    print(res["description"][:160], "...")
Enter fullscreen mode Exit fullscreen mode

Live output:

POST https://nettrux-edge.fly.dev/v1/immediate-bookings/commit
Bearer plus {quote_id}. The OpenAPI summary documents an x402 v1 402 challenge
when X-PAYMENT is absent, and verify, then settle, then book when it is present.
This entry does not name an asset, a chain, or a payee. ...
Enter fullscreen mode Exit fullscreen mode

Step 2 — Expect a 404 on the Edge discovery URL

The pointer names https://nettrux-edge.fly.dev/.well-known/x402 as the freight API discovery document. While EDGE_X402_DISCOVERY_PUBLISHED is false, that URL is not published by the API host. A 404 there is expected; the site pointer is still the catalog.

import urllib.error

EDGE_DISCOVERY = "https://nettrux-edge.fly.dev/.well-known/x402"
req = urllib.request.Request(
    EDGE_DISCOVERY,
    headers={"User-Agent": "nettrux-discovery-howto/1.0", "Accept": "application/json"},
)
try:
    urllib.request.urlopen(req, timeout=20)
except urllib.error.HTTPError as e:
    print("Edge discovery HTTP", e.code)
Enter fullscreen mode Exit fullscreen mode

Live output:

Edge discovery HTTP 404
Enter fullscreen mode Exit fullscreen mode

If your agent treats every 404 as "this 3PL does not support x402," you will miss Nettrux. Check the site pointer first. Only treat Edge discovery as authoritative once discoveryPublished flips to true and the gate says so.

Step 3 — Load the OpenAPI as the field contract

The discovery pointer points at the OpenAPI. That document is the request/response contract for every authenticated call. It is public and needs no token.

OPENAPI = "https://nettrux-edge.fly.dev/openapi.json"
req = urllib.request.Request(
    OPENAPI,
    headers={"User-Agent": "nettrux-discovery-howto/1.0", "Accept": "application/json"},
)
with urllib.request.urlopen(req, timeout=20) as r:
    oa = json.load(r)

paths = oa["paths"]
print(oa["info"]["title"], "openapi", oa["openapi"], "paths", len(paths))

commit = paths["/v1/immediate-bookings/commit"]["post"]
print("summary:", commit["summary"])
print("security:", commit["security"])
print("responses:", list(commit["responses"]))
body = commit["requestBody"]["content"]["application/json"]["schema"]
print("required body fields:", body["required"])
Enter fullscreen mode Exit fullscreen mode

Live output:

Nettrux Edge API openapi 3.0.3 paths 126
summary: Commit an immediate booking by PAYING for it over the x402 v1 handshake
(402 challenge without X-PAYMENT; verify → settle → book with it)
security: [{'bearerAuth': []}]
responses: ['200']
required body fields: ['quote_id']
Enter fullscreen mode Exit fullscreen mode

A few agent-relevant paths that exist today:

Path Methods Auth
/health, /ready GET none
/v1/rates/shop POST bearer
/v1/quotes GET, POST bearer
/v1/immediate-bookings/commit POST bearer
/v1/me GET bearer
/v1/agent/approvals GET bearer

The OpenAPI security scheme is HTTP bearer (JWT or API key). The public site does not issue tokens and does not describe self-serve signup. Guest checkout routes appear in the OpenAPI and stay flagged off — do not call them from these instructions.

Step 4 — Prove the health surface without a token

Unauthenticated health is a useful smoke check that the freight API host is up:

HEALTH = "https://nettrux-edge.fly.dev/health"
req = urllib.request.Request(
    HEALTH,
    headers={"User-Agent": "nettrux-discovery-howto/1.0", "Accept": "application/json"},
)
with urllib.request.urlopen(req, timeout=20) as r:
    health = json.load(r)
print(health["ok"], health["data"]["status"])
Enter fullscreen mode Exit fullscreen mode

Live output:

True healthy
Enter fullscreen mode Exit fullscreen mode

Commit without a bearer is rejected. Same day check:

import urllib.error

url = "https://nettrux-edge.fly.dev/v1/immediate-bookings/commit"
payload = json.dumps({"quote_id": "00000000-0000-4000-8000-000000000000"}).encode()
req = urllib.request.Request(
    url,
    data=payload,
    method="POST",
    headers={
        "Content-Type": "application/json",
        "User-Agent": "nettrux-discovery-howto/1.0",
    },
)
try:
    urllib.request.urlopen(req, timeout=20)
except urllib.error.HTTPError as e:
    print("HTTP", e.code, e.read().decode()[:180])
Enter fullscreen mode Exit fullscreen mode

Live output:

HTTP 401 {"ok":false,"data":null,"error":{"code":"missing_token",
"message":"Authorization: Bearer <token> is required"}, ...}
Enter fullscreen mode Exit fullscreen mode

That is the boundary: discovery is public; booking is authenticated; minting still requires a named human on the Nettrux side of the product.

Step 5 — Read the agent guide and llms.txt

After the JSON pointer, have the agent (or its author) read the prose contract:

  • Agent guide — discover → quote → book/pay via x402, with the gates listed at the top
  • llms.txt — the same gates and route list in a plain-text form models can ingest

Both returned HTTP 200 when we checked them for this article. The guide's instructions match the pointer: price-lock with POST /v1/quotes (quoteNumber, validUntil, rateInput), then call POST /v1/immediate-bookings/commit with { "quote_id": "..." } and no X-PAYMENT header for the documented 402 challenge. A paid retry carries the X-PAYMENT header an x402 v1 client builds from that challenge.

Because X402_REAL_MONEY_SETTLEMENT_LIVE is false, treat that handshake as documented, not as a claim that a public payment settles or books freight today.

A minimal discovery checklist for your agent

def discover_nettrux():
    """Public discovery only. Does not quote, book, or pay."""
    import json, urllib.request, urllib.error

    pointer = json.load(urllib.request.urlopen(
        urllib.request.Request(
            "https://www.nettrux.ai/.well-known/x402",
            headers={"Accept": "application/json",
                     "User-Agent": "nettrux-discovery-howto/1.0"},
        )
    ))
    gates = pointer["gates"]
    openapi = json.load(urllib.request.urlopen(
        urllib.request.Request(
            pointer["openapi"],
            headers={"Accept": "application/json",
                     "User-Agent": "nettrux-discovery-howto/1.0"},
        )
    ))

    return {
        "name": pointer["name"],
        "resource_host": pointer["resourceHost"],
        "resources_empty": pointer["resources"] == [],
        "gates": gates,
        "openapi_title": openapi["info"]["title"],
        "openapi_paths": len(openapi["paths"]),
        "commit_documented": "/v1/immediate-bookings/commit" in openapi["paths"],
        "ready_for_public_pay_and_book": (
            gates["EDGE_X402_DISCOVERY_PUBLISHED"]
            and gates["X402_REAL_MONEY_SETTLEMENT_LIVE"]
            and bool(pointer["resources"])
        ),
    }

print(discover_nettrux())
Enter fullscreen mode Exit fullscreen mode

Live output shape (abridged):

{
  'name': 'Nettrux',
  'resource_host': 'https://nettrux-edge.fly.dev',
  'resources_empty': True,
  'gates': {
    'EDGE_X402_DISCOVERY_PUBLISHED': False,
    'X402_REAL_MONEY_SETTLEMENT_LIVE': False,
    'GUEST_X402_CHECKOUT_ENABLED': False
  },
  'openapi_title': 'Nettrux Edge API',
  'openapi_paths': 126,
  'commit_documented': True,
  'ready_for_public_pay_and_book': False
}
Enter fullscreen mode Exit fullscreen mode

That last boolean is the whole point of honest discovery. An agent that can parse gates is an agent that will not invent a live rail that is not there.

After discovery: what still needs a human

Discovery gets you the map. Quoting and booking still need:

  1. A bearer token issued out of band (Nettrux does not publish self-serve API keys on the marketing site).
  2. A price-locked quote from POST /v1/quotes.
  3. A named human approving the mint — agents negotiate; humans approve everything that moves money or leaves the building; software is not an approver on this rail.

Shippers who just need freight moved today use the portal at nettrux.ai: LTL, FTL, and air are live; ocean is in build; tracking links and load documents do not require an agent.

FAQ

Is the public x402 pay-and-book endpoint live?

No. The discovery pointer is live. The resources array is empty. Discovery publish, real-money settlement, and guest checkout are all false.

Why publish an empty resources list?

So agents can find the OpenAPI, the freight API host, and the gate flags without guessing. An empty catalog with honest gates beats a marketing page that pretends settlement is open.

Can my agent call commit today?

Only with a bearer token Nettrux has already issued to your tenant, and only against the authenticated handshake documented in the OpenAPI. Without a token you get 401 missing_token. Public guest checkout is flagged off.

Does "first 3PL on x402" mean Nettrux is the only logistics company touching x402?

No. Other APIs sell logistics data over x402. The claim is about a 3PL building a native x402 transaction surface for the move itself.

Links

Questions for agent builders: dispatch@nettrux.net.

Alex Carney, Nettrux

Top comments (0)