> ## Documentation Index
> Fetch the complete documentation index at: https://docs.counsel.markets/llms.txt
> Use this file to discover all available pages before exploring further.

# Place a Bet

> A concrete walkthrough of the bet-intent flow: find a market and outcome, fetch an unsigned XRP Payment with projected odds, sign in your own wallet, and submit to the XRPL.

Placing a bet on counsel is placing a native XRP Payment. You send it to a market's pool account, with `DestinationTag` set to the outcome index and `SourceTag` set to counsel's attribution tag. counsel constructs the unsigned Payment and shows you the projected odds. You sign it in your own wallet and submit it. There is no deposit step and no counsel-side key in the path. The flow is non-custodial end to end.

This page walks the canonical developer path: `GET /markets` to find a market and outcome, then `GET /markets/:id/bet-intent` to get an unsigned Payment plus the projected odds after your stake, then sign and submit.

<Steps>
  <Step title="Find a market and outcome">
    List open markets and pick one. Each market carries its outcomes; the outcome index is what goes in `DestinationTag`.

    <CodeGroup>
      ```bash curl theme={null}
      curl https://api.counsel.markets/markets
      ```

      ```ts counsel-js theme={null}
      import { Counsel } from "counsel-js";

      const counsel = new Counsel({ baseUrl: "https://counsel.markets" });
      const { markets } = await counsel.markets();

      const market = markets[0];
      console.log(market.id, market.outcomes);
      ```
    </CodeGroup>

    You can also fetch a single market by id with `GET /markets/:id`.
  </Step>

  <Step title="Fetch a bet intent">
    Call `GET /markets/:id/bet-intent` with your `account`, the `outcome` index, and the `amount` in XRP. The response gives you an unsigned XRPL Payment ready to sign, plus the projected odds for that outcome after your stake is added to the pool.

    <CodeGroup>
      ```bash curl theme={null}
      curl "https://api.counsel.markets/markets/MARKET_ID/bet-intent?account=rYOUR_ADDRESS&outcome=0&amount=5"
      ```

      ```ts counsel-js theme={null}
      // counsel-js wraps fetch-intent, sign, and submit into one call.
      // To inspect the intent first, fetch it on its own:
      const intent = await counsel.betIntent({
        marketId: market.id,
        account: process.env.BOT_ADDRESS,
        outcome: 0,
        amount: 5,
      });

      console.log(intent.payment);            // unsigned XRPL Payment
      console.log(intent.projected_odds);     // projected odds after your stake
      ```
    </CodeGroup>

    <ParamField query="account" type="string" required>
      The XRPL address that will sign and send the bet. Used to address the unsigned Payment.
    </ParamField>

    <ParamField query="outcome" type="integer" required>
      The outcome index. This becomes the `DestinationTag` on the Payment.
    </ParamField>

    <ParamField query="amount" type="number" required>
      Your stake in XRP.
    </ParamField>

    The unsigned Payment is addressed to the market's pool account, with `DestinationTag` set to your outcome index and `SourceTag` set to counsel's attribution tag.

    <Note>
      The projected odds are indicative. counsel is parimutuel, so every later bet from any participant shifts the line until `bet_cutoff`. The split is computed from the actual pool state at close, not from the figure shown when you signed. See [Odds and Payouts](/concepts/fees-and-payouts).
    </Note>
  </Step>

  <Step title="Sign in your own wallet">
    Sign the unsigned Payment with your own key. counsel never sees your secret. In the app this is Xaman, GemWallet, or Crossmark; for a bot it is your client signing with its own seed.

    <Warning>
      Verify the `Destination`, `Amount`, `DestinationTag`, and `SourceTag` before signing. The `DestinationTag` is the outcome you are betting on; a wrong tag routes your stake to a different outcome pool.
    </Warning>
  </Step>

  <Step title="Submit to the XRPL">
    Submit the signed Payment to the XRPL. When it is included in a validated ledger, counsel reads it from the pool account's transaction history, routes your stake to the outcome pool named by `DestinationTag`, and updates the tote board.

    <CodeGroup>
      ```ts counsel-js theme={null}
      // placeBet does it all: fetch intent, sign with your key, submit.
      const hash = await counsel.placeBet(process.env.BOT_SEED, market.id, 0, 5);
      console.log("bet placed:", hash);
      ```
    </CodeGroup>
  </Step>
</Steps>

## The whole flow with counsel-js

`placeBet` collapses the four steps into one call: it fetches the unsigned intent, signs it with the seed you pass, and submits it. The seed stays on your machine.

```ts theme={null}
import { Counsel } from "counsel-js";

const counsel = new Counsel({ baseUrl: "https://counsel.markets" });
const { markets } = await counsel.markets();

// fetch an unsigned bet intent, sign with your own key, submit
const hash = await counsel.placeBet(process.env.BOT_SEED, markets[0].id, 0, 5);
console.log("bet placed:", hash);
```

## Non-custodial signing

counsel constructs the Payment but never holds it. The signing step happens entirely in your wallet or your client, with your key.

<CardGroup cols={2}>
  <Card title="counsel builds, you sign">
    The bet-intent endpoint returns an unsigned Payment. Signing and submitting are yours. counsel does not relay or proxy your signed transaction.
  </Card>

  <Card title="Pools are multisig">
    Stakes land in per-market accounts secured by a multisig SignerList with the master key disabled. No single key can move funds.
  </Card>

  <Card title="Everything is on-chain">
    Your bet is a tagged Payment in the pool account's transaction history. Anyone can index it and recompute the pool state.
  </Card>

  <Card title="Bots are first-class">
    A bot is an ordinary XRPL client: read a market, fetch an unsigned intent, sign with its own key, submit. Same path as the app.
  </Card>
</CardGroup>

## Tracking your position

After your bet lands, read it back by address.

<CodeGroup>
  ```bash curl theme={null}
  curl https://api.counsel.markets/accounts/rYOUR_ADDRESS/positions
  ```

  ```ts counsel-js theme={null}
  const { positions } = await counsel.positions(process.env.BOT_ADDRESS);
  console.log(positions);
  ```
</CodeGroup>

If your outcome wins, the payout Payment arrives at your address automatically after resolution. You do not claim or withdraw. If a pool is voided (one sided, no winner, cancelled event, or stale oracle), every stake is refunded in full with no fee.

<Tip>
  See the [API Reference](/api-reference) for the full set of read-only endpoints, including `/accounts/:address/feed`, `/accounts/:address/profile`, and `/leaderboard`.
</Tip>
