# Your First Payment

This guide walks through the full lifecycle of making an agent payment with RailProtocol: creating a wallet, setting spend policies, paying for an API service, and reading the on-chain record.

***

## What we are building

An agent that:

* Holds its own non-custodial Solana wallet
* Operates under a daily budget and a per-call spend limit
* Pays for a real data API call using x402
* Logs every payment to Solana with a verifiable transaction hash

***

## 1. Create the wallet

```bash
rail wallet create --agent research-agent
```

```
Agent wallet created.

  Agent:    research-agent
  Address:  7xKXtg2xpAGMq8KLwpSodE9LFKq8Z1EscezSShpump
  Balance:  0.00 USDC
  Network:  Solana Mainnet
```

The wallet is a program-derived address (PDA) on Solana. Only the agent's keypair can authorize payments from it. RailProtocol cannot move funds without a valid signed instruction.

Fund the wallet by transferring USDC to the address above, or via the dashboard at [app.railprotocol.org](https://app.railprotocol.org).

***

## 2. Set spend policies

Policies are checked at the gateway layer before any payment is submitted. A call that would breach the daily budget is rejected before funds leave the wallet.

```bash
rail policies set research-agent \
  --daily-budget 25 \
  --per-call-limit 1.00 \
  --allowed-domains "api.dune.com,api.browserbase.com,fal.ai" \
  --rate-limit "200 per hour"
```

Verify the policy is active:

```bash
rail policies get research-agent
```

```
Agent:           research-agent
Daily budget:    25.00 USDC
Per-call limit:  1.00 USDC
Allowed domains: api.dune.com, api.browserbase.com, fal.ai
Rate limit:      200 / hour
Protocol pref:   auto (x402 preferred)
```

***

## 3. Make a payment

Install the SDK and write the agent logic:

```typescript
import { RailProtocol } from "@railprotocol/sdk";

const rail = new RailProtocol({
  agentId: "research-agent",
  apiKey: process.env.RAIL_API_KEY,
});

async function queryData(queryId: string) {
  const result = await rail.pay({
    endpoint: `https://api.dune.com/v1/query/${queryId}/results`,
    method: "GET",
  });

  if (result.status !== 200) {
    throw new Error(`API returned ${result.status}`);
  }

  console.log("Protocol used:", result.protocol);     // "x402"
  console.log("Amount paid:", result.amountPaid);     // { usdc: 0.002 }
  console.log("Solana tx:", result.txHash);           // on-chain record
  console.log("Data:", result.data);                  // the API response

  return result.data;
}

const data = await queryData("1234");
```

`rail.pay()` handles everything: reading the 402 response, constructing the payment payload, signing with the agent's wallet, and retrying the original request with payment attached. The API response comes back in `result.data` as if the payment never happened.

***

## 4. Handle policy rejections

If a call would exceed the spend policy, RailProtocol rejects it before any funds are spent:

```typescript
import { PolicyViolationError } from "@railprotocol/sdk";

try {
  const result = await rail.pay({
    endpoint: "https://api.expensive-service.com/query",
    method: "POST",
    body: { query: "..." },
  });
} catch (err) {
  if (err instanceof PolicyViolationError) {
    console.error("Policy rejection:", err.reason);
    // "per_call_limit_exceeded: requested 2.50 USDC, limit is 1.00 USDC"
  }
}
```

Policy violations are also logged to the dashboard and can trigger webhook alerts.

***

## 5. View the on-chain record

List recent transactions for the agent:

```bash
rail transactions list --agent research-agent --limit 10
```

```
TX HASH                      PROTOCOL  AMOUNT      ENDPOINT                                  TIME
5yJ8kXtg2xp...mQ9pL         x402      0.002 USDC  api.dune.com/v1/query/1234/results        2 min ago
```

Inspect a single transaction:

```bash
rail transactions inspect 5yJ8kXtg2xp...mQ9pL
```

```
Transaction: 5yJ8kXtg2xp...mQ9pL
Agent:       research-agent
Protocol:    x402
Amount:      0.002 USDC
Endpoint:    api.dune.com/v1/query/1234/results
Policy:      passed
Solana:      https://explorer.solana.com/tx/5yJ8kXtg2xp...mQ9pL
Timestamp:   2026-05-09T14:23:01Z
```

The Solana link goes to the public explorer entry for the transaction. The ledger is independent of RailProtocol. Even if RailProtocol went offline, your payment history would remain on-chain.

***

## 6. View the dashboard

The dashboard at [app.railprotocol.org](https://app.railprotocol.org) shows real-time spend, protocol split, policy events, and a live transaction feed with links to Solana Explorer for every entry.

***

## Next steps

* [How the payment router selects protocols](/features/payment-router.md)
* [Full spend policy reference](/features/spend-policies.md)
* [Building multi-agent payment chains](/features/multi-agent-payments.md)
* [TypeScript SDK reference](/sdk/typescript.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.railprotocol.org/getting-started/your-first-payment.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
