Try the one-tool loop

Get a demo key.

Create a permit, invoke partner.echo, and fetch the portable receipt. This public demo uses a separate tenant and synthetic credits.

No account or payment needed.

Next: permit → invoke → portable receipt

After issuance, your key and wallet ID appear in these copy-paste commands. Run them in a terminal with Python 3 and curl.

API=https://api.thisisatest.tech
KEY='YOUR_DEMO_KEY'
WALLET='YOUR_WALLET_ID'
PERMIT_IDEM=$(python3 -c 'import uuid; print(uuid.uuid4().hex)')
EXPIRES=$(python3 -c 'from datetime import datetime,timedelta,timezone; print((datetime.now(timezone.utc)+timedelta(minutes=15)).isoformat())')

# 1. Create a permit for partner.echo.
PERMIT=$(curl -fsS -X POST "$API/v1/permits" \
  -H "X-API-Key: $KEY" -H "Idempotency-Key: $PERMIT_IDEM" \
  -H 'Content-Type: application/json' \
  -d "{\"issuer_wallet_id\":\"$WALLET\",\"subject_wallet_id\":\"$WALLET\",\"allowed_tools\":[\"partner.echo\"],\"scopes\":[\"tool:partner.echo:invoke\",\"billing:charge\"],\"max_credits\":\"5\",\"expires_at\":\"$EXPIRES\"}" \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["permit_id"])')

# 2. Invoke once with a fresh idempotency key.
CALL_IDEM=$(python3 -c 'import uuid; print(uuid.uuid4().hex)')
INVOKE=$(curl -fsS -X POST "$API/mcp/tools/partner.echo/invoke" \
  -H "X-API-Key: $KEY" -H 'Content-Type: application/json' \
  -d "{\"name\":\"partner.echo\",\"arguments\":{\"message\":\"hello from demo\"},\"mcp_context\":{\"wallet_id\":\"$WALLET\",\"permit_id\":\"$PERMIT\",\"idempotency_key\":\"$CALL_IDEM\"}}")
RECEIPT=$(printf '%s' "$INVOKE" | python3 -c 'import json,sys; print(json.load(sys.stdin)["receipt"]["receipt_id"])')

# 3. Fetch the portable receipt and public trust keys.
curl -fsS "$API/v1/receipts/$RECEIPT/portable" -H "X-API-Key: $KEY"
curl -fsS "$API/.well-known/trust-keys.json"

Terminal-only fallback for getting a key:

curl -s -X POST https://api.thisisatest.tech/v1/demo/keys