# API Reference

## Overview

All REST API methods read data from the Delphi API and require `DELPHI_API_ACCESS_KEY` to be set (except `health()`).

### health()

Check service availability. Does not require authentication.

```typescript
const { status } = await client.health();
```

### Markets

#### listMarkets(*params*)

Retrieve markets with optional filtering and pagination using `listMarkets`.

```typescript
const { markets } = await client.listMarkets({
  status: "open",
  category: "crypto",
  orderBy: "liquidity",    // "liquidity" | "created" | "settles_at"
  verifiable: true,
  skip: 0,
  limit: 50,
});
```

#### **Parameters**

| Field      | Type     | Default | Description                           |
| ---------- | -------- | ------- | ------------------------------------- |
| `skip`     | `number` | `0`     | Pagination offset                     |
| `limit`    | `number` | `50`    | Max records returned                  |
| `status`   | `string` | —       | `"open"` \| `"closed"` \| `"settled"` |
| `category` | `string` | —       | Filter by metadata category field     |

#### getMarket(*params*)

Retrieve a single market by ID.

```typescript
const market = await client.getMarket({ id: "0xMarketContractAddress" });
```

{% hint style="info" %}
This returns the same `Market` type. The `id` comes from `listMarkets`.
{% endhint %}

#### Market Type

```typescript
export interface Market {
  id: string; // On-chain contract address of the market proxy
  appMarketId: string; // UUID identifying the market in the Delphi app UI
  marketUrl: string; // Direct link to the market on the Delphi app
  status: string; // Market lifecycle status, e.g. "open", "closed", or "settled"
  category: string; // Market category, e.g. "crypto", "sports", "politics"
  deployer: string; // Wallet address that deployed/created the market
  implementation: string; // Market implementation contract address
  metadataUri: string; // URI pointing to the market metadata
  metadataUriContentHash: string; // Content hash for the metadata URI
  metadata: unknown; // Parsed market metadata returned by the API
  dataSources: unknown; // Data sources used for market resolution/verification
  createdAt: string; // ISO timestamp when the market was created
  fetchedAt: string | null; // ISO timestamp when metadata was last fetched, or null
  fetchResponseStatus: string | null; // Status from the metadata fetch attempt, or null
  resolvesAt: string | null; // ISO timestamp when the market is expected to resolve, or null
  settledAt: string | null; // ISO timestamp when the market was settled, or null
  settlesAt: string | null; // ISO timestamp for scheduled settlement, or null
  winningOutcomeIdx: string | null; // Winning outcome index after settlement, or null
  tradingFee: string | null; // Trading fee value returned by the API, or null
  proof: string | null; // Resolution proof or verification reference, or null
  error: string | null; // Error message related to market metadata/resolution, or null
  verifiable: boolean; // Whether the market has verifiable settlement enabled
}
```

#### Metadata Shape

```typescript
const meta = market.metadata as {
  question?: string;            // The market question
  title?: string;               // Alternative title
  description?: string;
  category?: string;
  outcomes?: string[];          // Outcome labels — index matches outcomeIdx
  resolutionCriteria?: string;
  endDate?: string;             // ISO date
} | null;
```

{% hint style="danger" %}
The `outcomes` array is critical for labelling: `outcomes[0]` is the label for `outcomeIdx: 0`.
{% endhint %}

The key address fields here are:

| Field                   | Purpose                                                               |
| ----------------------- | --------------------------------------------------------------------- |
| `market.id`             | Pass to `getMarket({ id })`                                           |
| `market.implementation` | Pass as `marketAddress` to all SDK trading, quote, and approval calls |

### Market Status Values

```typescript
type MarketStatus = "open" | "awaiting_settlement" | "settled" | "expired";
```

| Status                | Meaning                                                      |
| --------------------- | ------------------------------------------------------------ |
| `open`                | Trading active                                               |
| `awaiting_settlement` | Trading deadline passed, awaiting settlement                 |
| `settled`             | Winner submitted, positions redeemable                       |
| `expired`             | Market expired without settlement (positions not redeemable) |

{% hint style="info" %}
The API returns these as *strings*.&#x20;

The underlying contract exposes them as an `int enum`: 0 -> open, 1 -> awaiting\_settlement, 2 -> settled, 3 -> expired.
{% endhint %}

### Usage Patterns

You can paginate through all markets like this:

```typescript
let skip = 0;
const limit = 50;
const all: Market[] = [];

while (true) {
  const { markets } = await client.listMarkets({ status: "open", skip, limit });
  if (!markets || markets.length === 0) break;
  all.push(...markets);
  if (markets.length < limit) break;
  skip += limit;
}
```

Or, find a market using a question keyword:

```typescript
const { markets } = await client.listMarkets({ status: "open", limit: 100 });
const match = markets?.find(m => {
  const meta = m.metadata as { question?: string } | null;
  return meta?.question?.toLowerCase().includes("keyword");
});
```

### Positions

#### listPositions(*params*)

Retrieve positions for a wallet address.

```typescript
const { positions } = await client.listPositions({
  wallet: "0xYourWalletAddress",
  redeemedOrLiquidated: false,
  skip: 0,
  limit: 50,
});
```

#### Position Type

```typescript
interface Position {
  id: string;
  marketProxy: string;      // Market proxy address (use as marketAddress)
  wallet: string;
  outcomeIdx: string;       // Outcome index as string — parse with parseInt()
  shares: string;           // 18-decimal bigint as string — parse with BigInt()
  redeemedOrLiquidated: boolean;
  tokensRedeemed: string;   // 6-decimal bigint as string — parse with BigInt()
  marketStatus: "open" | "awaiting_settlement" | "settled" | "expired";
}
```

Be careful when parsing, because `shares` and `tokensRedeemed` are *string representations* of [bigints](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html#bigint).&#x20;

```typescript
const shares = Number(BigInt(position.shares)) / 1e18;
const tokensRedeemed = Number(BigInt(position.tokensRedeemed)) / 1e6;
const outcomeIdx = parseInt(position.outcomeIdx);
```

### Redemption

Markets must be `settled` (winner submitted) before redeeming. Only holders of the winning outcome receive tokens.

{% hint style="warning" %}
Positions with `shares === "0"` cannot be redeemed or liquidated because the wallet holds no stake.&#x20;

The positions API may return zero-share entries for markets the wallet previously participated in but fully exited. Always check `BigInt(position.shares) > 0n` before attempting redeem or liquidate calls.
{% endhint %}

#### 1. Single (Market) Redemption

```typescript
const { transactionHash, sharesIn, tokensOut } = await client.redeemMarket({
  marketAddress: "0x..." as `0x${string}`,
});
console.log(`Redeemed ${Number(sharesIn) / 1e18} shares → ${Number(tokensOut) / 1e6} USDC`);
```

#### 2. Batch (Market) Redemption

```typescript
const { results, totalTokensOut } = await client.redeemPositions({
  marketAddresses: ["0x...", "0x..."],
});

for (const r of results) {
  if (r.success) {
    console.log(`${r.marketAddress}: ${Number(r.tokensOut!) / 1e6} USDC`);
  } else {
    console.error(`${r.marketAddress}: ${r.error}`);
  }
}
console.log(`Total redeemed: ${Number(totalTokensOut) / 1e6} USDC
```

#### 3. Batch-Redeeming all Unredeemed, Settled Positions

```typescript
const { positions } = await client.listPositions({
  wallet: myAddress,
  redeemedOrLiquidated: false,
});

const settledProxies: `0x${string}`[] = [];
for (const p of positions ?? []) {
  if (BigInt(p.shares) === 0n) continue;
  const market = await client.getMarket({ id: p.marketProxy });
  if (market.status === "settled") {
    settledProxies.push(p.marketProxy as `0x${string}`);
  }
}

if (settledProxies.length > 0) {
  const { results, totalTokensOut } = await client.redeemPositions({
    marketAddresses: settledProxies,
  });
}
```

#### Estimating Portfolio Value

Estimate the current liquidation value of all active positions:

```typescript
const { positions } = await client.listPositions({
  wallet: myAddress,
  redeemedOrLiquidated: false,
});

let totalValue = 0;
for (const p of positions ?? []) {
  const shares = BigInt(p.shares);
  if (shares === 0n) continue;

  const marketAddress = p.marketProxy as `0x${string}`;
  const outcomeIdx = parseInt(p.outcomeIdx);

  try {
    const { tokensOut } = await client.quoteSell({
      marketAddress, outcomeIdx, sharesIn: shares,
    });
    totalValue += Number(tokensOut) / 1e6;
  } catch {
    console.log(`${marketAddress} outcome ${outcomeIdx}: cannot quote (market may be closed)`);
  }
}
console.log(`Total estimated value: ${totalValue.toFixed(4)} USDC`);
```


---

# 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.gensyn.ai/tech/delphi-sdk/api.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.
