Docs — licita-agent

Discovery order (for agents)

  1. GET /llms.txt — concise machine-readable service description.
  2. GET /openapi.json — full REST schema.
  3. GET /v1/pricing — machine-readable price ladder + payment flow.
  4. Call paid endpoints, paying per call (below), or use MCP at /mcp.

Payment flow (x402 v2)

Priced endpoints require a payment per call. Unpaid requests get HTTP 402 with the exact requirement in a base64 PAYMENT-REQUIRED response header ({ x402Version: 2, resource, accepts: [{ scheme, network, asset, amount, payTo, maxTimeoutSeconds, extra }] }).

  1. Call a paid endpoint without payment → 402 + PAYMENT-REQUIRED header.
  2. Sign an EIP-3009 transferWithAuthorization of USDC for the advertised amount on the advertised network (scheme exact) with an x402 client, producing a base64 payment payload.
  3. Retry the original request with PAYMENT-SIGNATURE: <payload> (v2). The legacy v1 header X-PAYMENT is still accepted for backward compatibility.
  4. The server verifies and settles the payment through its facilitator before serving content; proofs are single-use.

Local development only (PAYMENTS_MODE=x402): when the payments mode is dev, POST /v1/dev-faucet mints a dev token instead — retry with X-PAYMENT: <token>. The faucet is not available in production.

# 1. Try a paid endpoint without payment → HTTP 402 + base64 PAYMENT-REQUIRED header
curl -i 'http://localhost:3000/v1/search?q=software&type=award'
# → 402
#   PAYMENT-REQUIRED: ", amount: "", payTo: "", ... }] }>

# 2. Sign an EIP-3009 transferWithAuthorization of USDC with an x402 client
#    (or viem directly) from the PAYMENT-REQUIRED requirement → base64 payload 

# 3. Retry with the payment payload (v2; legacy X-PAYMENT also accepted)
curl -s 'http://localhost:3000/v1/search?q=software&type=award' \
  -H "PAYMENT-SIGNATURE: "
# → {"data":[...],"meta":{"paid":true,"price_usd":"0.02",...}}

# 4. Local development only (PAYMENTS_MODE=dev): mint a dev token instead
curl -s -X POST 'http://localhost:3000/v1/dev-faucet' \
  -H 'content-type: application/json' \
  -d '{"endpoint":"GET /v1/search"}'
# → {"token":"","proof":"","endpoint":"GET /v1/search","amount":"0.02","expires_at":"..."}
curl -s 'http://localhost:3000/v1/search?q=software&type=award' \
  -H "X-PAYMENT: "

Endpoints

EndpointPrice (USD / call)
GET /v1/search$0.02
GET /v1/tenders/:id$0.02
GET /v1/companies/:id$0.05
GET /v1/companies/:id/awards$0.05
GET /v1/companies/:id/opportunities$0.10
GET /v1/buyers/:id/history$0.05
GET /v1/renewals$0.25
GET /v1/pricingfree
GET /v1/statsfree

GET /v1/stats additionally requires header x-operator-key. Common query params: page, size (≤100), cpv (prefix), region (NUTS), from/to (YYYY-MM-DD).

MCP

Streamable-HTTP MCP server at POST /mcp (transport is free; tools are priced like their REST equivalents). Each tool accepts an optional payment_token argument — the base64 payment payload (the same value a REST client sends as PAYMENT-SIGNATURE). Unpaid calls return {"payment_required": true, "price_usd": "...", "how_to_pay": {...}} as normal content (not an error) — parse it, create the payment with an x402 client from the PAYMENT-REQUIRED requirement, and retry with payment_token set. In dev mode how_to_pay points at the faucet instead.

# tools/list then e.g.
{"jsonrpc":"2.0","id":1,"method":"tools/call",
 "params":{"name":"search_tenders",
           "arguments":{"q":"software","type":"award","payment_token":""}}}

Conventions