# AI Coding Resources
Source: https://pond.dflow.net/build/ai-coding
Files that make the DFlow docs agent-ready
## MCP Server
The fastest way to connect AI tools to DFlow documentation is through our
[MCP server](/build/mcp). It gives tools like Cursor, VS Code, Claude, and
Claude Code direct access to our docs and API specs during code generation.
* Server URL: `https://pond.dflow.net/mcp`
* Setup guide: [MCP Server](/build/mcp)
## Phantom Connect Skill for Claude
The [Phantom Connect skill](https://github.com/DFlowProtocol/dflow_phantom-connect-skill), built with [Phantom](https://phantom.app), teaches Claude how to use Phantom's wallet SDKs and DFlow's trading APIs to build full-stack crypto apps. It covers wallet connection, transaction signing, token swaps, prediction markets, and KYC verification.
You can also install it using [Vercel's `skill` CLI](https://skills.sh/):
```bash theme={null}
npx skills add https://github.com/DFlowProtocol/dflow_phantom-connect-skill
```
## AI-Facing Files
These files give agents structured access to DFlow documentation:
### `skill.md`
`skill.md` is a structured capability file that tells agents what they can do
with DFlow, what inputs they need, and what constraints apply. If you're
building with agents, start here.
* View: [`/skill.md`](/skill.md)
### `llms.txt`
`llms.txt` is an index of the DFlow docs. It lists key pages with descriptions
so agents can find answers quickly.
* View: [`/llms.txt`](/llms.txt)
### `llms-full.txt`
`llms-full.txt` is the full, expanded index for agents that want complete
coverage.
* View: [`/llms-full.txt`](/llms-full.txt)
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# API Keys
Source: https://pond.dflow.net/build/api-key
How to request an API key for production use
Developer endpoints work without an API key, however they are rate limited and not suitable for production use.
For production use, [fill out this form](https://docs.google.com/forms/d/e/1FAIpQLSeKr847cQWIKSBmOM_iexwxGY3AtB-dEOnYQqrRjYsT8lScEA/viewform?usp=publish-editor) to receive an API key with higher rate limits. We will get back to you within 2-5 days.
Once you have an API key, [see this recipe](/build/recipes/api-keys) for example code showing how to use it.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Endpoints
Source: https://pond.dflow.net/build/endpoints
DFlow endpoints for Trading and Prediction Markets APIs
DFlow has separate endpoints for spot token trading and prediction markets.
| Service | Endpoint |
| ---------------------- | ------------------------------------------------------ |
| Trade API | `https://dev-quote-api.dflow.net` |
| Trade API WebSocket | `wss://dev-quote-api.dflow.net/priority-fees/stream` |
| Metadata API | `https://dev-prediction-markets-api.dflow.net` |
| Metadata API WebSocket | `wss://dev-prediction-markets-api.dflow.net/api/v1/ws` |
Keep in mind:
* These endpoints are intended for end-to-end testing during development.
* Do not ship to production without coordinating with the DFlow team.
* Be prepared to lose test capital.
* Endpoints are rate-limited and not suitable for production workloads.
For production use, [builders should reach out to support](/build/api-key) to receive an API key with higher rate limits.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Error Codes
Source: https://pond.dflow.net/build/error-codes
Understanding and resolving error codes
Kalshi's clearinghouse has a weekly maintenance window on **Thursdays from
3:00 AM to 5:00 AM ET**. Orders submitted during this window will not be
cleared. The order will be reverted.
Your application should prevent users from submitting orders during this
window.
## General HTTP errors
| Code | Title | When it happens | How to fix |
| ---- | ------------------- | ----------------------------------- | ---------------------------------------------------------------------------- |
| 429 | Rate limit exceeded | Too many requests in a short window | Retry with backoff, reduce request rate, or use an [API key](/build/api-key) |
## Trading API
### `route_not_found`
This error is most common in three situations:
1. **Wrong `outputMint` for prediction markets.** If you are selling an outcome
token, `outputMint` must match the market's settlement mint. We currently
support two settlement mints:
* USDC: `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`
* CASH: `CASHx9KJUStyftLFWGvEVf59SGeG9sh5FfcnZMVPCASH`
You can resolve this by using the settlement
mint listed in the market's `accounts` object.
2. **Incorrect `amount` units.** The `amount` parameter is the `inputMint`
amount in atomic units (scaled by decimals). If you pass standard
(human-readable) units (for example `8` instead of `8_000_000`), the router will not find a viable route.
3. **No liquidity at the top of book.** For outcome tokens, `route_not_found`
can mean there is no available bid/ask on the side the user wants to trade.
**How to check**
* Get the market for the outcome token:
* `GET https://dev-prediction-markets-api.dflow.net/api/v1/market/by-mint/{outcome_mint}` (See [Metadata API](/build/metadata-api/markets/market-by-mint))
* Use your production Metadata API base URL in production.
* See which side the user is on:
* In the response, open the `accounts` object and find the entry whose
`yesMint` or `noMint` equals the outcome mint.
* If it matches `yesMint`, they are trading the YES outcome.
* If it matches `noMint`, they are trading the NO outcome.
* Check the right bid or ask using the top-level fields from the same market response:
* Selling YES → check `yesBid`. If it is `null` (or empty), there is no one to buy.
* Selling NO → check `noBid`. If it is `null` (or empty), there is no one to buy.
* Buying YES → check `yesAsk`. If it is `null` (or empty), no one is offering YES.
* Buying NO → check `noAsk`. If it is `null` (or empty), no one is offering NO.
### `price_impact_too_high`
The effective price during routing is worse than the allowed threshold. If unspecified, the server determines the default. To set your own threshold, pass [`priceImpactTolerancePct`](/build/trading-api/order/order#parameter-price-impact-tolerance-pct).
## Prediction Markets IDL
| Code | Name | Message |
| ---- | ----------------------- | ------------------------------------ |
| 16 | MarketNotOpen | Market is not open |
| 17 | MarketOutcomeDetermined | Market outcome is already determined |
| 18 | MarketNotDetermined | Market is not determined |
| 19 | InvalidMarketStatus | Invalid market status |
| 64 | InvalidQuantity | Invalid quantity |
| 80 | OrderAlreadyFilled | Order already filled |
| 81 | InvalidFillQuantity | Invalid fill quantity |
| 82 | InvalidMarketOutcome | Invalid market outcome |
| 83 | FillUnderproduced | Produced output \< min output amount |
| 84 | FillOverconsumed | Consumed input > max input amount |
| 96 | Underflow | Underflow |
| 97 | Overflow | Overflow |
| 255 | Unknown | Unknown error |
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# FAQs
Source: https://pond.dflow.net/build/faqs
Answers to common questions about building with DFlow
Any Solana wallet that supports standard transaction signing is compatible.
Slippage depends on market liquidity and trade size, while fees include network fees plus any DEX, priority, or platform fees applied at execution.
Yes, trades are non-custodial and do not require KYC, unless your application adds its own requirements.
Sync trades settle atomically in one transaction, while async trades span multiple transactions; prediction markets are async because market interactions cannot be completed atomically.
No, user funds remain in the user’s wallet throughout the entire trade lifecycle.
Because when a market is uninitialized, the /order endpoint performs on-demand market tokenization (creating the YES/NO outcome tokens) before executing the swap, which incurs a small onchain account creation fee. See the full explanation [here](/build/recipes/prediction-markets/trade-into-position).
You can implement gasless swaps with our [sponsor parameter](/build/trading-api/order/order#parameter-sponsor).
No. Only specify a nonzero `platformFeeBps` if you will actually collect the fee at execution time. The API factors the declared fee into slippage tolerance calculations, so declaring a fee you don't collect wastes slippage budget and results in suboptimal pricing for your users. See [Platform Fees](/build/trading/platform-fees#how-platform-fees-affect-trades) for details.
No. The Trading API does not set CORS headers, so browser requests will be blocked. You must proxy `/order` calls through your own backend. Most builders use a lightweight edge function (Cloudflare Workers, Vercel Edge Functions, etc.) to keep the added latency minimal.
No.
[Imperative trades](/learn/imperative-trades) give the app full control over routes and execution, while [declarative trades](/learn/declarative-trades) let DFlow handle routing based on constraints you specify.
This is currently on our roadmap, but we do not have a timeline for when it will be supported.
JIT routing re-optimizes routes onchain at execution time instead of relying on a fixed route decided upfront.
[Priority fees](/build/trading/priority-fees) are added to transactions to improve inclusion and execution speed during network congestion.
Yes. DFlow supports Pump.fun tokens both while they are still on the bonding curve and after they have graduated to PumpSwap (Pump.fun's native AMM).
Slippage is receiving a worse price than expected between when a quote is generated and when the trade executes. Price impact is the difference between the market price and the effective price you get during routing, caused by the size of your trade relative to available liquidity.
The server determines the threshold, and trades that exceed it are rejected with a `price_impact_too_high` error. To set your own threshold, pass [`priceImpactTolerancePct`](/build/trading-api/order/order#parameter-price-impact-tolerance-pct).
Use the WSOL mint (`So11111111111111111111111111111111111111112`) in `inputMint` or `outputMint` and set `wrapAndUnwrapSol=true`. The API will auto-wrap or auto-unwrap SOL for the user.
Use the destination wallet address, not the wallet's WSOL associated token account address.
The transaction hit its compute unit (CU) limit.
Fix this by passing `dynamicComputeUnitLimit=true` in your `/order` request, which instructs the API to determine the appropriate CU limit dynamically.
In multi-leg routes, intermediate token accounts can be created to pass value from one leg to the next. Two outcomes can occur:
* **Full consumption (zero residual):** If the full intermediate amount is consumed by subsequent legs, we can close intermediate accounts.
* **Partial consumption (small residual dust):** If a nonzero residual remains, we do not close intermediate accounts. This can happen when venue constraints prevent exact full consumption of the produced amount.
You can access the API via our [developer endpoints](/build/endpoints) now, for production use, you'll need an [API key](/build/api-key) to avoid rate limits.
Yes. You have to use [`platformFeeScale`](/build/trading/platform-fees#platformfeescale).
We support two settlement mints at the moment, USDC and CASH. The market will settle in whichever settlement mint the outcome token mint belongs to. See [this recipe](/build/recipes/prediction-markets/redeem-outcome-tokens) for more details.
We don’t currently have images on markets (just events). Adding images for markets is being worked on currently, but for now you can fetch these [from Kalshi directly](https://docs.kalshi.com/api-reference/events/get-event-metadata).
Initialization is about **0.02 SOL** and is paid in SOL (not USDC). This fee applies only when a market is not yet tokenized.
Any platform developer can pre-initialize a market before users start trading it. Otherwise, the first user’s trade initializes the market and incurs the initialization cost unless the trade is sponsored. DFlow pre-initializes some popular markets.
Yes. Using the settlement mint (USDC or CASH) as the input is the fastest path. If you input a different token (e.g., SOL), the system adds a swap leg to convert to the settlement mint first, which adds roughly **50ms** of latency. For the lowest latency prediction market trades, use the settlement mint directly.
The minimum is **0.01 USDC**, but some markets require more because the smallest purchasable unit is one contract and the minimum depends on the contract price.
No.
They are outcome tokens that represent positions in a prediction market.
After resolution, users redeem outcome tokens for value according to the market result. This creates a second phase of UX that does not exist in spot trading: redemption flows, position closeout UX, and history and receipts UX.
[Prediction market fees](/build/prediction-markets/prediction-market-fees) are calculated based on trading volume and are subject to a fee tier system.
Forecast history is only supported for numerical events and is separated by percentiles. It’s best suited for research or analysis rather than UI/UX. Use candlesticks for charting and user-facing price history.
There is a maximum of **5,000 candlesticks per request**. If your `startTs`, `endTs`, and `periodInterval` parameters would produce more than 5,000 candlesticks, the request will fail. Either narrow the time range or increase the period interval.
[Prediction market tokens](/learn/prediction-market-tokens) are tokens that represent positions in a prediction market. They are minted when a user enters a position and burned when a user redeems a position. The liquidity for prediction market tokens comes from the [Concurrent Liquidity Programs (CLPs)](/learn/clp).
[Prediction market lifecycle](/build/recipes/prediction-markets/monitor-market-lifecycle) is a fixed sequence from creation to final settlement. A market's status defines what actions users and builders can take at each stage.
No. Kalshi's clearinghouse has a weekly maintenance window on **Thursdays from 3:00 AM to 5:00 AM ET**. Orders submitted during this window will not be cleared. The order will be reverted. Your application should prevent users from submitting orders during this window.
The DFlow WebSockets currently show all Kalshi trades (both onchain and offchain).
Yes. Onchain trades through DFlow hit Kalshi's offchain order books, so they appear on Kalshi's trade websocket the same way offchain trades do.
We don’t. DFlow market tickers map directly to Kalshi tickers, so use Kalshi’s [Market Ticker websocket](https://docs.kalshi.com/websockets/market-ticker) for streaming open interest and [Get Market](https://docs.kalshi.com/api-reference/market/get-market) for per-market snapshots.
Yes, DFlow supports all of Kalshi's markets (including entertainment, culture, and celebrity) except for combos.
No. The [`/submit-intent`](/build/trading-api/prediction-market/prediction-market-submit-intent) endpoint builds the order and returns a transaction, but you still need to sign and submit the transaction via an RPC to execute it. USDC is only pulled from the wallet when the transaction lands onchain.
Omit `userPublicKey` from the [`/order`](/build/trading-api/order/order) request. The API returns the quote without requiring Proof verification, so unverified users can preview pricing before completing KYC.
Yes. Kalshi market tickers map directly to the DFlow API. You can fetch a specific market by its ticker using the [Get Market](/build/metadata-api/markets/market) endpoint, or look up all markets under an event using the [Get Event](/build/metadata-api/events/event) endpoint.
Use the [Get Orderbook](/build/metadata-api/orderbook/orderbook-by-ticker) endpoint to fetch the current best bid and best ask for a market. This lets you estimate how many contracts a user will receive at a given price before submitting an order. For real-time updates, you can also stream orderbook changes via the [Orderbook WebSocket channel](/build/metadata-api/websockets/orderbook).
A **Milestone** groups a real-world occurrence (e.g. a game or match) by bundling related event tickers together for convenience. It is not part of the Series → Event → Market hierarchy — it is a separate grouping layer.
`related_event_tickers` is a superset of `primary_event_tickers`. Primary event tickers are generally limited to moneyline, spread, and total markets for a sporting event.
The relationship is typically one Milestone to many event tickers, but can be many-to-many, a single event ticker can appear in multiple Milestones, so there is no strict parent/child hierarchy.
If you are passing `isInitialized=true` on the [Events](/build/metadata-api/events/events), [Markets](/build/metadata-api/markets/markets), or [Series](/build/metadata-api/series/series) endpoints, the response will only include markets that have already been tokenized through a DFlow trade. Markets that are live on Kalshi but haven't been traded through DFlow yet will be filtered out. This is especially common with short-duration markets (e.g., 15-minute crypto price markets like KXBTC15M) where a new market starts every interval. Remove the `isInitialized` filter to see all active markets. See [Market Initialization Behavior](/build/prediction-markets/prediction-market-data-model#market-initialization-behavior) for details.
We use [Stripe Identity](https://docs.stripe.com/identity) for KYC.
No.
Yes. KYC verifies user identity, but geoblocking is still required because
prediction markets are not permitted in all jurisdictions. Use geoblocking
to restrict access where local regulations do not allow prediction markets.
Yes. Proof verification is required when buying outcome tokens on both developer and production endpoints. Selling does not require verification. See [Understanding KYC for Prediction Markets](/build/prediction-markets/kyc) for details.
Proof only redirects to `https:`, `moz-extension://`, and `chrome-extension:` URLs. If your `redirect_uri` uses a custom scheme (e.g. `myapp://callback`), the redirect will silently fail. Native mobile apps should use [universal links](https://developer.apple.com/ios/universal-links/) (iOS) or [app links](https://developer.android.com/training/app-links) (Android), which use `https:` URLs that deep link into your app. See the [redirect\_uri parameter docs](/build/proof/partner-integration#deep-link-parameters) for details.
Omit `userPublicKey` from the [`/order`](/build/trading-api/order/order) request to get a quote without verification.
Yes. Proof works with embedded wallet providers. Your app directs the user to `https://dflow.net/proof` to complete KYC, and you can provide a [redirect URL](/build/proof/partner-integration#deep-link-parameters) to send the user back to your app after verification.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Introduction
Source: https://pond.dflow.net/build/introduction
How to get started building with DFlow
These recipes assume familiarity with Solana's transaction and network connection logic.
If unfamiliar, please read the [Solana Cookbook](https://solana.com/developers/cookbook).
## General
Learn how to authenticate requests with API keys for production usage.
Endpoints for Trading and Prediction Markets APIs.
Request an API key.
## Trading Tokens
Build trading functionality for spot and prediction markets using DFlow's unified APIs. Trade tokens with [automatic routing](/learn/declarative-trade) [across major Solana DEXs](/learn/liquidity-venues), supporting both synchronous (atomic) and asynchronous (multi-transaction) execution modes.
Execute declarative trades where routing is optimized at execution time.
Execute imperative trades with full control over the route plan.
Add platform fees to monetize trading volume.
Control execution speed with priority fees.
Trade prediction market tokens.
## Prediction Markets
Integrate prediction markets into your app. Discover
markets, track positions, and redeem outcomes using our APIs.
Discover markets and outcome token mints using the Metadata API.
Trade from spot tokens into outcome tokens using the Trade API.
Track positions by mapping wallet balances to markets and outcomes.
Add size to an existing position with controlled execution.
Reduce position size or close exposure with a single trade.
Track market status changes and redemption availability.
Handle prediction market fees.
Redeem determined outcome tokens when markets settle.
Burn remaining tokens and reclaim rent.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# MCP Server
Source: https://pond.dflow.net/build/mcp
Connect AI tools to DFlow documentation and API references with our hosted MCP server.
The DFlow MCP server gives AI tools direct access to our documentation, API specs, and code examples so they can generate accurate, up-to-date code for your integration.
```
https://pond.dflow.net/mcp
```
## What is MCP?
[Model Context Protocol](https://modelcontextprotocol.io/) (MCP) is an open standard that connects AI applications to external data sources. Instead of relying on general web search, your AI tool searches DFlow documentation directly during response generation, giving you current API methods, correct parameters, and working examples.
## Connecting to the DFlow MCP Server
Use the contextual menu at the top of any documentation page for one-click setup, or follow the manual instructions below.
Run the following command:
```bash theme={null}
claude mcp add --transport http DFlow https://pond.dflow.net/mcp
```
Or add to your project's `.mcp.json`:
```json theme={null}
{
"mcpServers": {
"DFlow": {
"type": "http",
"url": "https://pond.dflow.net/mcp"
}
}
}
```
Verify with:
```bash theme={null}
claude mcp list
```
1. Go to [Connectors](https://claude.ai/settings/connectors) in your Claude settings.
2. Select **Add custom connector**.
3. Set the name to `DFlow` and the URL to `https://pond.dflow.net/mcp`.
4. When chatting, click the attachments button (plus icon) and select the DFlow connector.
Install in Cursor
To connect the DFlow MCP server to Cursor, click the **Install in Cursor** button above. Or to manually connect the MCP server, follow these steps:
1. Open the command palette with `Cmd + Shift + P` (or `Ctrl + Shift + P` on Windows).
2. Search for **Open MCP settings**.
3. Add the following to your `mcp.json`:
```json theme={null}
{
"mcpServers": {
"DFlow": {
"url": "https://pond.dflow.net/mcp"
}
}
}
```
Create a `.vscode/mcp.json` file in your project and add:
```json theme={null}
{
"servers": {
"DFlow": {
"type": "http",
"url": "https://pond.dflow.net/mcp"
}
}
}
```
1. Open the command palette with `Cmd + Shift + P` (or `Ctrl + Shift + P` on Windows).
2. Search for **Windsurf: Configure MCP Servers**.
3. Add the following to your `mcp_config.json`:
```json theme={null}
{
"mcpServers": {
"DFlow": {
"serverUrl": "https://pond.dflow.net/mcp"
}
}
}
```
## What You Get
Once connected, your AI tool can search DFlow documentation while generating responses. This includes:
* **Trading API**: Order, imperative, and declarative endpoints with parameters and examples.
* **Metadata API**: Prediction market discovery, orderbooks, candlesticks, websockets.
* **Proof API**: KYC verification endpoints.
* **Code Recipes**: End-to-end implementation patterns for common use cases.
* **Concepts**: How routing, slippage, priority fees, and platform fees work.
* **Debugging**: Draws from a large FAQ library that is continuously updated based on real integration questions from builders, so your AI tool can troubleshoot issues using the same answers our team gives in support channels.
The MCP server is automatically generated from this documentation and stays in sync as pages are updated.
## Example Prompts
Try these with the DFlow MCP server connected:
**Arbitrage and Market Scanning**
* "Build a scanner that finds active prediction markets where the combined YES and NO ask prices sum to less than \$1."
* "Write a function that monitors orderbook depth across markets and flags any where the top-of-book spread is wider than 5 cents."
**Automated Trading Bots**
* "Write a bot that streams websocket price updates and automatically buys YES when the ask drops below a target price."
* "Build an auto-redemption bot that polls for markets transitioning to determined status and redeems winning outcome tokens immediately."
* "Write a script that monitors market lifecycle status and places a trade the moment a market goes active."
**Position Management**
* "Build a portfolio tracker that maps a wallet's outcome token balances to their current market prices and shows unrealized P\&L."
* "Write a function that automatically decreases a position when the bid price hits a take-profit target."
* "How do I track all my open prediction market positions and calculate total exposure?"
**Execution Optimization**
* "Write an imperative trade that routes through a single DEX using the dexes parameter for deterministic execution."
* "How do I use USDC as the input mint to skip the spot swap leg and get the lowest latency prediction market trade?"
* "How do I use priority fee presets like auto, medium, high, and veryHigh to speed up time-sensitive trades?"
**Trading Basics**
* "Write a TypeScript function that executes an imperative token swap on DFlow with custom slippage."
* "How do I add dynamic platform fees to prediction market trades?"
* "How do I trade BONK into a prediction market outcome token position?"
**Debugging**
* "My trade is returning `route_not_found`, how do I debug this?"
* "Why is my swap transaction failing onchain after getting a successful quote?"
## Tips
* **Be specific**: "How do I submit a declarative trade with platform fees?" works better than "help with trading."
* **Mention your stack**: "Using TypeScript and Next.js, show me how to..." gives better results.
* **Iterate**: Use generated code as a starting point and ask for modifications.
* **Prepare**: Read the docs first, so you know how to properly frame your commands.
## Other AI Resources
For tools that don't support MCP, see [AI Coding Resources](/build/ai-coding).
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Event
Source: https://pond.dflow.net/build/metadata-api/events/event
GET /api/v1/event/{event_id}
API reference for GET /api/v1/event/{event_id}
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Event Candlesticks
Source: https://pond.dflow.net/build/metadata-api/events/event-candlesticks
GET /api/v1/event/{ticker}/candlesticks
API reference for GET /api/v1/event/{ticker}/candlesticks
There is a maximum of **5,000 candlesticks per request**. If your `startTs`, `endTs`, and `periodInterval` parameters would produce more than 5,000 results, the request will return a 400 error. Either narrow the time range or increase the period interval.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Events
Source: https://pond.dflow.net/build/metadata-api/events/events
GET /api/v1/events
API reference for GET /api/v1/events
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Event Forecast Percentile History
Source: https://pond.dflow.net/build/metadata-api/events/forecast-percentile-history
GET /api/v1/event/{series_ticker}/{event_id}/forecast_percentile_history
API reference for GET /api/v1/event/{series_ticker}/{event_id}/forecast_percentile_history
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Event Forecast Percentile History by Mint
Source: https://pond.dflow.net/build/metadata-api/events/forecast-percentile-history-by-mint
GET /api/v1/event/by-mint/{mint_address}/forecast_percentile_history
API reference for GET /api/v1/event/by-mint/{mint_address}/forecast_percentile_history
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Introduction
Source: https://pond.dflow.net/build/metadata-api/introduction
How to discover crypto and prediction market metadata.
Query and retrieve event information and forecast data
Access prediction market data and information
Get orderbook data for prediction markets
Retrieve trade history for prediction markets
Get live data from Kalshi for milestones and events
Get series templates for recurring events
Access tags organized by series categories
Get filtering options organized by sports
Search events with nested markets by title or ticker
Stream real-time price and trade updates via WebSocket
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Live Data
Source: https://pond.dflow.net/build/metadata-api/live-data/live-data
GET /api/v1/live_data
API reference for GET /api/v1/live_data
This endpoint passes through live data from the Kalshi API. The JSON response includes a `details` object on each item whose structure varies by sport or category. See the [Live Data Response Details](/build/metadata-api/live-data/live-data-details) reference for the full field breakdown.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Live Data by Event
Source: https://pond.dflow.net/build/metadata-api/live-data/live-data-by-event
GET /api/v1/live_data/by-event/{event_ticker}
API reference for GET /api/v1/live_data/by-event/{event_ticker}
This endpoint passes through live data from the Kalshi API. The JSON response includes a `details` object on each item whose structure varies by sport or category. See the [Live Data Response Details](/build/metadata-api/live-data/live-data-details) reference for the full field breakdown.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Live Data by Mint
Source: https://pond.dflow.net/build/metadata-api/live-data/live-data-by-mint
GET /api/v1/live_data/by-mint/{mint_address}
API reference for GET /api/v1/live_data/by-mint/{mint_address}
This endpoint passes through live data from the Kalshi API. The JSON response includes a `details` object on each item whose structure varies by sport or category. See the [Live Data Response Details](/build/metadata-api/live-data/live-data-details) reference for the full field breakdown.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Live Data Response Details
Source: https://pond.dflow.net/build/metadata-api/live-data/live-data-details
Reference for the details field in live data responses
The live data endpoints (`/api/v1/live_data`, `/api/v1/live_data/by-event`, and `/api/v1/live_data/by-mint`) return responses passed through from the Kalshi API. Each response item includes a `details` object whose structure is determined by the **milestone type** (sport or category), not unique per instance.
The `details` object uses `additionalProperties: true` in the upstream API spec, so it is a flexible key-value object rather than a strict schema. The fields below represent the known, consistent fields for each milestone type.
## Common Fields
These fields appear across all milestone types:
| Field | Type | Description |
| ---------------- | -------- | ------------------------------------------------------ |
| `type` | `string` | The milestone type identifier |
| `status` | `string` | Game/event status: `"none"`, `"live"`, or `"finished"` |
| `widgetLiveText` | `string` | Display text for live widget UI |
| `tileLiveText` | `string` | Display text for tile UI |
| `scheduled` | `string` | Scheduled start time |
| `winner` | `string` | Winner identifier (when applicable) |
### Team Sports Common Fields
Most team-based sports include these fields for the home and away sides:
| Field | Type | Description |
| ----------------------------------------- | ------------------ | ------------------------------------- |
| `home_points` / `away_points` | `number` | Current score |
| `home_abbreviation` / `away_abbreviation` | `string` | Team abbreviation |
| `home_name` / `away_name` | `string` | Full team name |
| `home_short_name` / `away_short_name` | `string` | Short team name |
| `home_image_url` / `away_image_url` | `string` | Team logo URL |
| `home_id` / `away_id` | `string` | Team identifier |
| `home_rank` / `away_rank` | `number \| string` | Team ranking (optional) |
| `home_is_first` | `boolean` | Whether the home team is listed first |
## Sport-Specific Fields
### Football
| Field | Type | Description |
| ----------------------- | ------------------ | -------------------------------------------- |
| `leg` | `string` | Current period or leg |
| `possession` | `"home" \| "away"` | Team currently in possession |
| `last_play` | `string` | Description of the most recent play |
| `sub_title` | `string` | Additional context (e.g., down and distance) |
| `round` | `number` | Current round |
| `final_round_time_left` | `string` | Time remaining in the final round |
### Soccer
| Field | Type | Description |
| ----------------------------------------------------- | ---------- | ------------------------------------------ |
| `aggregate_text` | `string` | Aggregate score text (multi-leg matches) |
| `show_penalties` | `boolean` | Whether the match is in a penalty shootout |
| `home_penalties` / `away_penalties` | `string[]` | Penalty kick results per attempt |
| `home_penalties_score` / `away_penalties_score` | `number` | Total penalty score |
| `home_significant_events` / `away_significant_events` | `object[]` | Notable match events (goals, cards, etc.) |
### Tennis
| Field | Type | Description |
| ------------------------------------------------------- | ---------- | ------------------------------------- |
| `advantage` | `string` | Player with advantage in current game |
| `server` | `string` | Player currently serving |
| `home_current_round_score` / `away_current_round_score` | `string` | Score in the current game |
| `home_seed` / `away_seed` | `number` | Player seeding |
| `home_round_scores` / `away_round_scores` | `object[]` | Scores for each set |
| `home_country` / `away_country` | `string` | Player nationality |
### Golf
| Field | Type | Description |
| ------------- | ---------- | ------------------------------------------------------------- |
| `leaderboard` | `object[]` | Array of leaderboard entries with player positions and scores |
### MMA
| Field | Type | Description |
| ----------------- | -------- | ------------------------------------------------------ |
| `methodOfVictory` | `string` | How the fight was won (e.g., KO, submission, decision) |
| `fightLength` | `number` | Duration of the fight |
### Racing
| Field | Type | Description |
| --------------- | -------- | ------------------------ |
| `completedLaps` | `number` | Number of laps completed |
| `totalLaps` | `number` | Total laps in the race |
### Baseball
| Field | Type | Description |
| ------------- | ----------- | ----------------------------------------- |
| `balls` | `number` | Current ball count |
| `strikes` | `number` | Current strike count |
| `outs` | `number` | Current out count |
| `inning` | `number` | Current inning |
| `inning_half` | `number` | Top or bottom of the inning |
| `bases` | `boolean[]` | Base occupancy (`[first, second, third]`) |
### Cricket
| Field | Type | Description |
| ------------------------------- | -------- | --------------- |
| `home_overs` / `away_overs` | `number` | Overs completed |
| `home_wickets` / `away_wickets` | `number` | Wickets fallen |
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Filter Outcome Mints
Source: https://pond.dflow.net/build/metadata-api/markets/filter-outcome-mints
POST /api/v1/filter_outcome_mints
API reference for POST /api/v1/filter_outcome_mints
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Market
Source: https://pond.dflow.net/build/metadata-api/markets/market
GET /api/v1/market/{market_id}
API reference for GET /api/v1/market/{market_id}
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Market by Mint
Source: https://pond.dflow.net/build/metadata-api/markets/market-by-mint
GET /api/v1/market/by-mint/{mint_address}
API reference for GET /api/v1/market/by-mint/{mint_address}
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Market Candlesticks
Source: https://pond.dflow.net/build/metadata-api/markets/market-candlesticks
GET /api/v1/market/{ticker}/candlesticks
API reference for GET /api/v1/market/{ticker}/candlesticks
There is a maximum of **5,000 candlesticks per request**. If your `startTs`, `endTs`, and `periodInterval` parameters would produce more than 5,000 results, the request will return a 400 error. Either narrow the time range or increase the period interval.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Market Candlesticks by Mint
Source: https://pond.dflow.net/build/metadata-api/markets/market-candlesticks-by-mint
GET /api/v1/market/by-mint/{mint_address}/candlesticks
API reference for GET /api/v1/market/by-mint/{mint_address}/candlesticks
There is a maximum of **5,000 candlesticks per request**. If your `startTs`, `endTs`, and `periodInterval` parameters would produce more than 5,000 results, the request will return a 400 error. Either narrow the time range or increase the period interval.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Markets
Source: https://pond.dflow.net/build/metadata-api/markets/markets
GET /api/v1/markets
API reference for GET /api/v1/markets
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Markets Batch
Source: https://pond.dflow.net/build/metadata-api/markets/markets-batch
POST /api/v1/markets/batch
API reference for POST /api/v1/markets/batch
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Outcome Mints
Source: https://pond.dflow.net/build/metadata-api/markets/outcome-mints
GET /api/v1/outcome_mints
API reference for GET /api/v1/outcome_mints
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Orderbook by Mint Address
Source: https://pond.dflow.net/build/metadata-api/orderbook/orderbook-by-mint
GET /api/v1/orderbook/by-mint/{mint_address}
API reference for GET /api/v1/orderbook/by-mint/{mint_address}
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Orderbook
Source: https://pond.dflow.net/build/metadata-api/orderbook/orderbook-by-ticker
GET /api/v1/orderbook/{market_ticker}
API reference for GET /api/v1/orderbook/{market_ticker}
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Search Events
Source: https://pond.dflow.net/build/metadata-api/search/search
GET /api/v1/search
API reference for GET /api/v1/search
## What Search Covers
Search uses a multi-field, full-text query across **events** and **markets**.
### Events (fields searched)
* `id` (event ticker)
* `series_ticker` (series ticker)
* `title`
* `sub_title`
### Markets (fields searched)
* `id` (market ticker)
* `event_ticker`
* `title`
* `yes_sub_title`
* `no_sub_title`
### Fields Not Searched
Search does **not** query tags, categories, rules, competition fields, images,
or settlement sources.
## How Matching Works
* The query is split on whitespace; **all tokens** must match.
* Ticker fields (`id`, `series_ticker`, `event_ticker`) match **upper and lower**
variants.
* Text fields (`title`, `sub_title`, `yes_sub_title`, `no_sub_title`) use
full-text matching.
* Special characters are escaped before search.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Series
Source: https://pond.dflow.net/build/metadata-api/series/series
GET /api/v1/series
API reference for GET /api/v1/series
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Series by Ticker
Source: https://pond.dflow.net/build/metadata-api/series/series-by-ticker
GET /api/v1/series/{series_ticker}
API reference for GET /api/v1/series/{series_ticker}
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Filters by Sports
Source: https://pond.dflow.net/build/metadata-api/sports/filters-by-sports
GET /api/v1/filters_by_sports
API reference for GET /api/v1/filters_by_sports
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Tags by Categories
Source: https://pond.dflow.net/build/metadata-api/tags/tags-by-categories
GET /api/v1/tags_by_categories
API reference for GET /api/v1/tags_by_categories
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Onchain Trades
Source: https://pond.dflow.net/build/metadata-api/trades/onchain-trades
GET /api/v1/onchain-trades
API reference for GET /api/v1/onchain-trades
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Onchain Trades by Event
Source: https://pond.dflow.net/build/metadata-api/trades/onchain-trades-by-event
GET /api/v1/onchain-trades/by-event/{event_ticker}
API reference for GET /api/v1/onchain-trades/by-event/{event_ticker}
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Onchain Trades by Market
Source: https://pond.dflow.net/build/metadata-api/trades/onchain-trades-by-market
GET /api/v1/onchain-trades/by-market/{market_ticker}
API reference for GET /api/v1/onchain-trades/by-market/{market_ticker}
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Trades
Source: https://pond.dflow.net/build/metadata-api/trades/trades
GET /api/v1/trades
API reference for GET /api/v1/trades
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Trades by Mint
Source: https://pond.dflow.net/build/metadata-api/trades/trades-by-mint
GET /api/v1/trades/by-mint/{mint_address}
API reference for GET /api/v1/trades/by-mint/{mint_address}
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Orderbook Channel
Source: https://pond.dflow.net/build/metadata-api/websockets/orderbook
Subscribe to real-time orderbook updates for prediction markets
The `orderbook` channel streams real-time orderbook updates for prediction markets. Use this channel to build orderbook visualizations, depth charts, and market depth analysis tools.
## Connection
See the [WebSocket overview](/build/metadata-api/websockets/overview#connection) for connection setup and endpoint details.
## Subscribe
### Subscribe to All Orderbooks
```json theme={null}
{
"type": "subscribe",
"channel": "orderbook",
"all": true
}
```
### Subscribe to Specific Tickers
```json theme={null}
{
"type": "subscribe",
"channel": "orderbook",
"tickers": ["BTCD-25DEC0313-T92749.99", "SPX-25DEC0313-T5000"]
}
```
## Unsubscribe
### Unsubscribe from All Orderbooks
```json theme={null}
{
"type": "unsubscribe",
"channel": "orderbook",
"all": true
}
```
### Unsubscribe from Specific Tickers
```json theme={null}
{
"type": "unsubscribe",
"channel": "orderbook",
"tickers": ["BTCD-25DEC0313-T92749.99"]
}
```
## Response Format
When subscribed to the `orderbook` channel, you'll receive messages with the following structure:
```json theme={null}
{
"channel": "orderbook",
"type": "orderbook",
"market_ticker": "BTCD-25DEC0313-T92749.99",
"yes_bids": {
"0.45": 1000,
"0.44": 500,
"0.43": 200
},
"no_bids": {
"0.55": 1500,
"0.56": 800,
"0.57": 300
}
}
```
### Response Fields
| Field | Type | Description |
| --------------- | ------ | --------------------------------------------------------------- |
| `channel` | string | Always `"orderbook"` |
| `type` | string | Message type |
| `market_ticker` | string | Market identifier |
| `yes_bids` | object | Map of price (string) to quantity (number) for YES outcome bids |
| `no_bids` | object | Map of price (string) to quantity (number) for NO outcome bids |
The `yes_bids` and `no_bids` fields are objects where keys are price strings
and values are quantities. The order of entries in these objects represents
the orderbook depth.
## Code Examples
```typescript theme={null}
// Dev endpoint — no API key required, but rate-limited.
// For production, use your production WS URL and add:
// { headers: { "x-api-key": "YOUR_API_KEY" } }
// as the second argument to new WebSocket().
const WS_URL = "wss://dev-prediction-markets-api.dflow.net/api/v1/ws";
const ws = new WebSocket(WS_URL);
ws.onopen = () => {
console.log("Connected to WebSocket");
// Subscribe to all orderbook updates
ws.send(
JSON.stringify({
type: "subscribe",
channel: "orderbook",
all: true,
})
);
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.channel === "orderbook") {
console.log("Orderbook update:", {
ticker: message.market_ticker,
yesBids: message.yes_bids,
noBids: message.no_bids,
});
}
};
ws.onerror = (error) => {
console.error("WebSocket error:", error);
};
ws.onclose = () => {
console.log("WebSocket connection closed");
};
```
```typescript theme={null}
import "dotenv/config";
const API_KEY = process.env.DFLOW_API_KEY;
const WS_URL = process.env.DFLOW_PREDICTION_MARKETS_WS_URL;
// Market tickers to subscribe to
const marketTickers = ["BTCD-25DEC0313-T92749.99", "SPX-25DEC0313-T5000"];
if (!WS_URL || !API_KEY) {
throw new Error(
"Missing websocket credentials. Set DFLOW_PREDICTION_MARKETS_WS_URL and DFLOW_API_KEY."
);
}
const ws = new WebSocket(WS_URL, {
headers: {
"x-api-key": API_KEY,
},
});
ws.onopen = () => {
console.log("Connected to WebSocket");
// Subscribe to specific tickers for orderbooks
ws.send(
JSON.stringify({
type: "subscribe",
channel: "orderbook",
tickers: marketTickers,
})
);
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log(`Orderbook update for ${message.market_ticker}:`, message);
};
```
```typescript theme={null}
interface OrderbookUpdate {
channel: "orderbook";
type: string;
market_ticker: string;
yes_bids: Record;
no_bids: Record;
}
```
## Related
Subscribe to real-time bid/ask price updates
Subscribe to real-time trade execution updates
Get orderbook snapshots via REST API
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Websockets Overview
Source: https://pond.dflow.net/build/metadata-api/websockets/overview
Stream real-time price, trade, and orderbook updates via WebSocket
The WebSocket API provides real-time streaming of market data, including price updates, trade executions, and orderbook depth. Connect once and receive continuous updates for the markets you're interested in.
The WebSocket API is ideal for building real-time trading interfaces, price
tickers, and trade feeds. For historical data or one-time queries, use the
[REST API endpoints](/metadata-api/introduction).
Looking for Trading API WebSocket streams? See the
[Trading API Websockets overview](/build/trading-api/websockets/overview).
## Connection
The dev WebSocket URL is:
```
wss://dev-prediction-markets-api.dflow.net/api/v1/ws
```
This endpoint does not require an API key. For production, use the `wss:` protocol with your Prediction Markets API host and the `/api/v1/ws` path:
```
wss:///api/v1/ws
```
## Channels
The WebSocket API supports three channels:
| Channel | Description |
| ----------- | --------------------------------------------- |
| `prices` | Real-time bid/ask price updates for markets |
| `trades` | Real-time trade execution updates |
| `orderbook` | Real-time orderbook depth updates for markets |
Subscribe to real-time bid/ask price updates for prediction markets
Subscribe to real-time trade execution updates
Subscribe to real-time orderbook depth updates
## Subscription Management
After connecting, send JSON messages to subscribe or unsubscribe from channels. Each channel maintains independent subscription state.
### Subscribe to All Markets
Subscribe to receive updates for all markets on a channel:
```json theme={null}
{
"type": "subscribe",
"channel": "prices",
"all": true
}
```
### Subscribe to Specific Tickers
Subscribe to receive updates for specific market tickers:
```json theme={null}
{
"type": "subscribe",
"channel": "prices",
"tickers": ["BTCD-25DEC0313-T92749.99", "SPX-25DEC0313-T5000"]
}
```
### Unsubscribe from All Markets
Unsubscribe from all markets on a channel:
```json theme={null}
{
"type": "unsubscribe",
"channel": "prices",
"all": true
}
```
### Unsubscribe from Specific Tickers
Unsubscribe from specific market tickers:
```json theme={null}
{
"type": "unsubscribe",
"channel": "prices",
"tickers": ["BTCD-25DEC0313-T92749.99"]
}
```
Unsubscribing from specific tickers has no effect if you are subscribed to
"all" for that channel. You must first unsubscribe from "all" before managing
individual ticker subscriptions.
### Subscription Behavior
* Subscribing to `"all": true` clears any specific ticker subscriptions for that channel.
* Subscribing to specific tickers disables "all" mode for that channel.
* Each channel (`prices`, `trades`, and `orderbook`) maintains independent subscription state.
* You can be subscribed to all prices while only subscribing to specific tickers for trades or orderbooks, or any combination.
* In `"all"` mode, you receive all channel updates, including updates from markets created after the subscription is established.
## Quick Start Example
```typescript theme={null}
// Dev endpoint — no API key required, but rate-limited.
// For production, use your production WS URL and add:
// { headers: { "x-api-key": "YOUR_API_KEY" } }
// as the second argument to new WebSocket().
const WS_URL = "wss://dev-prediction-markets-api.dflow.net/api/v1/ws";
const ws = new WebSocket(WS_URL);
ws.onopen = () => {
console.log("Connected to WebSocket");
// Subscribe to all price updates
ws.send(
JSON.stringify({
type: "subscribe",
channel: "prices",
all: true,
})
);
// Subscribe to all trade updates
ws.send(
JSON.stringify({
type: "subscribe",
channel: "trades",
all: true,
})
);
// Subscribe to all orderbook updates
ws.send(
JSON.stringify({
type: "subscribe",
channel: "orderbook",
all: true,
})
);
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
switch (message.channel) {
case "prices":
console.log("Price update:", message);
break;
case "trades":
console.log("Trade update:", message);
break;
case "orderbook":
console.log("Orderbook update:", message);
break;
}
};
ws.onerror = (error) => {
console.error("WebSocket error:", error);
};
ws.onclose = () => {
console.log("WebSocket connection closed");
};
```
## Best Practices
Implement reconnection logic with exponential backoff to handle
disconnections gracefully.
Subscribe only to the markets you need. Use specific tickers rather than
"all" when possible to reduce bandwidth.
Process messages asynchronously to avoid blocking the WebSocket connection
during high-volume periods.
Always implement `onerror` and `onclose` handlers to detect and respond to
connection issues.
## Next Steps
Find market tickers to subscribe to using the REST API
Execute trades on markets you're monitoring
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Prices Channel
Source: https://pond.dflow.net/build/metadata-api/websockets/prices
Subscribe to real-time bid/ask price updates for prediction markets
The `prices` channel streams real-time bid and ask price updates for prediction markets. Use this channel to build live price tickers, trading interfaces, and market monitoring tools.
## Connection
See the [WebSocket overview](/build/metadata-api/websockets/overview#connection) for connection setup and endpoint details.
## Subscribe
### Subscribe to All Prices
```json theme={null}
{
"type": "subscribe",
"channel": "prices",
"all": true
}
```
### Subscribe to Specific Tickers
```json theme={null}
{
"type": "subscribe",
"channel": "prices",
"tickers": ["BTCD-25DEC0313-T92749.99", "SPX-25DEC0313-T5000"]
}
```
## Unsubscribe
### Unsubscribe from All Prices
```json theme={null}
{
"type": "unsubscribe",
"channel": "prices",
"all": true
}
```
### Unsubscribe from Specific Tickers
```json theme={null}
{
"type": "unsubscribe",
"channel": "prices",
"tickers": ["BTCD-25DEC0313-T92749.99"]
}
```
## Response Format
When subscribed to the `prices` channel, you'll receive messages with the following structure:
```json theme={null}
{
"channel": "prices",
"type": "ticker",
"market_ticker": "BTCD-25DEC0313-T92749.99",
"yes_bid": "0.45",
"yes_ask": "0.47",
"no_bid": "0.53",
"no_ask": "0.55"
}
```
### Response Fields
| Field | Type | Description |
| --------------- | -------------- | ------------------------------ |
| `channel` | string | Always `"prices"` |
| `type` | string | Message type |
| `market_ticker` | string | Market identifier |
| `yes_bid` | string \| null | Best bid price for YES outcome |
| `yes_ask` | string \| null | Best ask price for YES outcome |
| `no_bid` | string \| null | Best bid price for NO outcome |
| `no_ask` | string \| null | Best ask price for NO outcome |
Price fields may be `null` if there is no current bid or ask at that level.
## Code Examples
```typescript theme={null}
// Dev endpoint — no API key required, but rate-limited.
// For production, use your production WS URL and add:
// { headers: { "x-api-key": "YOUR_API_KEY" } }
// as the second argument to new WebSocket().
const WS_URL = "wss://dev-prediction-markets-api.dflow.net/api/v1/ws";
const ws = new WebSocket(WS_URL);
ws.onopen = () => {
console.log("Connected to WebSocket");
// Subscribe to all price updates
ws.send(
JSON.stringify({
type: "subscribe",
channel: "prices",
all: true,
})
);
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.channel === "prices") {
console.log("Price update:", {
ticker: message.market_ticker,
yesBid: message.yes_bid,
yesAsk: message.yes_ask,
noBid: message.no_bid,
noAsk: message.no_ask,
});
}
};
ws.onerror = (error) => {
console.error("WebSocket error:", error);
};
ws.onclose = () => {
console.log("WebSocket connection closed");
};
```
```typescript theme={null}
// Dev endpoint — no API key required, but rate-limited.
// For production, use your production WS URL and add:
// { headers: { "x-api-key": "YOUR_API_KEY" } }
// as the second argument to new WebSocket().
const WS_URL = "wss://dev-prediction-markets-api.dflow.net/api/v1/ws";
// Market tickers to subscribe to
const marketTickers = ["BTCD-25DEC0313-T92749.99", "SPX-25DEC0313-T5000"];
const ws = new WebSocket(WS_URL);
ws.onopen = () => {
console.log("Connected to WebSocket");
// Subscribe to specific tickers for prices
ws.send(
JSON.stringify({
type: "subscribe",
channel: "prices",
tickers: marketTickers,
})
);
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log(`Price update for ${message.market_ticker}:`, message);
};
```
```typescript theme={null}
interface PriceUpdate {
channel: "prices";
type: string;
market_ticker: string;
yes_bid: string | null;
yes_ask: string | null;
no_bid: string | null;
no_ask: string | null;
}
function handlePriceUpdate(update: PriceUpdate) {
console.log(`Price update for ${update.market_ticker}:`, {
yesBid: update.yes_bid,
yesAsk: update.yes_ask,
noBid: update.no_bid,
noAsk: update.no_ask,
});
}
```
## Related
Subscribe to real-time trade execution updates
Subscribe to real-time orderbook depth updates
Get live data snapshots via REST API
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Trades Channel
Source: https://pond.dflow.net/build/metadata-api/websockets/trades
Subscribe to real-time trade execution updates
The `trades` channel streams real-time trade execution updates for prediction markets. Use this channel to build trade feeds, activity monitors, and market analysis tools.
## Connection
See the [WebSocket overview](/build/metadata-api/websockets/overview#connection) for connection setup and endpoint details.
## Subscribe
### Subscribe to All Trades
```json theme={null}
{
"type": "subscribe",
"channel": "trades",
"all": true
}
```
`all: true` streams all trades on the channel, including trades from markets created after the subscription is established.
### Subscribe to Specific Tickers
```json theme={null}
{
"type": "subscribe",
"channel": "trades",
"tickers": ["BTCD-25DEC0313-T92749.99", "SPX-25DEC0313-T5000"]
}
```
## Unsubscribe
### Unsubscribe from All Trades
```json theme={null}
{
"type": "unsubscribe",
"channel": "trades",
"all": true
}
```
### Unsubscribe from Specific Tickers
```json theme={null}
{
"type": "unsubscribe",
"channel": "trades",
"tickers": ["BTCD-25DEC0313-T92749.99"]
}
```
## Response Format
When subscribed to the `trades` channel, you'll receive messages with the following structure:
```json theme={null}
{
"channel": "trades",
"type": "trade",
"market_ticker": "BTCD-25DEC0313-T92749.99",
"trade_id": "abc123",
"price": 47,
"count": 100,
"yes_price": 47,
"no_price": 53,
"yes_price_dollars": "0.47",
"no_price_dollars": "0.53",
"taker_side": "yes",
"created_time": 1702744800000
}
```
### Response Fields
| Field | Type | Description |
| ------------------- | ------ | ------------------------------------- |
| `channel` | string | Always `"trades"` |
| `type` | string | Always `"trade"` |
| `market_ticker` | string | Market identifier |
| `trade_id` | string | Unique trade identifier |
| `price` | number | Trade execution price |
| `count` | number | Number of contracts traded |
| `yes_price` | number | YES outcome price at execution |
| `no_price` | number | NO outcome price at execution |
| `yes_price_dollars` | string | YES price formatted in dollars |
| `no_price_dollars` | string | NO price formatted in dollars |
| `taker_side` | string | Side of the taker (`"yes"` or `"no"`) |
| `created_time` | number | Unix timestamp in milliseconds |
## Code Examples
```typescript theme={null}
// Dev endpoint — no API key required, but rate-limited.
// For production, use your production WS URL and add:
// { headers: { "x-api-key": "YOUR_API_KEY" } }
// as the second argument to new WebSocket().
const WS_URL = "wss://dev-prediction-markets-api.dflow.net/api/v1/ws";
const ws = new WebSocket(WS_URL);
ws.onopen = () => {
console.log("Connected to WebSocket");
// Subscribe to all trade updates
ws.send(
JSON.stringify({
type: "subscribe",
channel: "trades",
all: true,
})
);
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.channel === "trades") {
console.log("Trade executed:", {
ticker: message.market_ticker,
tradeId: message.trade_id,
side: message.taker_side,
count: message.count,
yesPrice: message.yes_price_dollars,
noPrice: message.no_price_dollars,
time: new Date(message.created_time).toISOString(),
});
}
};
ws.onerror = (error) => {
console.error("WebSocket error:", error);
};
ws.onclose = () => {
console.log("WebSocket connection closed");
};
```
```typescript theme={null}
// Dev endpoint — no API key required, but rate-limited.
// For production, use your production WS URL and add:
// { headers: { "x-api-key": "YOUR_API_KEY" } }
// as the second argument to new WebSocket().
const WS_URL = "wss://dev-prediction-markets-api.dflow.net/api/v1/ws";
// Market tickers to subscribe to
const marketTickers = ["BTCD-25DEC0313-T92749.99", "SPX-25DEC0313-T5000"];
const ws = new WebSocket(WS_URL);
ws.onopen = () => {
console.log("Connected to WebSocket");
// Subscribe to specific tickers for trades
ws.send(
JSON.stringify({
type: "subscribe",
channel: "trades",
tickers: marketTickers,
})
);
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log(`Trade on ${message.market_ticker}:`, message);
};
```
```typescript theme={null}
interface TradeUpdate {
channel: "trades";
type: "trade";
market_ticker: string;
trade_id: string;
price: number;
count: number;
yes_price: number;
no_price: number;
yes_price_dollars: string;
no_price_dollars: string;
taker_side: "yes" | "no";
created_time: number;
}
function handleTradeUpdate(update: TradeUpdate) {
console.log(`Trade executed on ${update.market_ticker}:`, {
tradeId: update.trade_id,
side: update.taker_side,
count: update.count,
yesPrice: update.yes_price_dollars,
noPrice: update.no_price_dollars,
time: new Date(update.created_time).toISOString(),
});
}
```
## Related
Subscribe to real-time bid/ask price updates
Subscribe to real-time orderbook depth updates
Query historical trade data via REST API
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Transaction Fee Sponsorship
Source: https://pond.dflow.net/build/prediction-markets/fee-sponsorship
How to sponsor user transaction fees and prediction market initialization costs
Apps often sponsor **transaction fees** and **ATA creation** for users by acting as the transaction’s fee payer. When trading prediction markets, there is an additional cost category to be aware of: **prediction market initialization**, which creates outcome mints and related onchain accounts.
On Solana, wallets do not hold tokens directly. Each wallet must have an
Associated Token Account (ATA) for a specific SPL token. If the ATA does not
exist yet, it must be created onchain (with rent paid by a designated payer)
before the wallet can receive or trade that token.
## What you can sponsor
There are three distinct costs involved in prediction market trades:
* **Transaction fees** (paid by the fee payer)
* **Associated token account (ATA) creation**
* **Prediction market initialization** (market tokenization)
DFlow exposes separate controls depending on which costs you want your application to cover.
## Sponsor transaction fees and market initialization
Use the [`sponsor`](/build/trading-api/order/order#parameter-sponsor)
parameter when you want your application to act as the fee payer and also cover
prediction market initialization costs.
This is the simplest option when fully sponsoring user transactions.
## Sponsor market initialization only
If you want users to pay their own transaction fees, but want your application
to pay for **prediction market initialization**, set
[`predictionMarketInitPayer`](/build/trading-api/order/order#parameter-prediction-market-init-payer)
to the address that should fund market initialization.
This is useful when users are already signing and paying for transactions, but you don’t want them to incur the one-time cost of initializing an uninitialized market.
## Initialize markets ahead of time
To avoid initializing a market during a user trade, you can initialize it ahead
of time using the utility endpoint below.
### Initialize Prediction Market
[`GET /prediction-market-init`](/build/trading-api/prediction-market/prediction-market-init)
**Query parameters**
* `payer` (required): Base58-encoded address that pays for initialization.
* `outcomeMint` (required): Base58-encoded mint address of either outcome token.
**Response**
* `transaction` (required): Base64-encoded transaction that initializes the market.\
The `payer` must sign this transaction before submitting it.
Pre-initializing markets is useful for backend workflows or when you want the first user trade to execute without additional setup.
## Notes
* Prediction market initialization is a one-time onchain cost per market.
* If a market is uninitialized, initialization can occur automatically during a trade unless handled separately.
* Sponsorship configuration determines who pays for transaction fees versus market initialization.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Understanding KYC for Prediction Markets
Source: https://pond.dflow.net/build/prediction-markets/kyc
How Proof verification affects prediction market trading and how to handle unverified users
Buying prediction market outcome tokens requires [Proof](/learn/proof) verification to meet Kalshi compliance requirements. This page covers how verification affects API behavior and how to build around it.
Spot trading does not require Proof.
## Which Wallet Needs to Be Verified
The wallet receiving the outcome tokens must be verified:
* If [`destinationWallet`](/build/trading-api/order/order#parameter-destination-wallet) is specified, that wallet needs to be verified.
* If `destinationWallet` is unspecified, [`userPublicKey`](/build/trading-api/order/order#parameter-user-public-key) needs to be verified, since the user's wallet is the default destination.
* The fee payer does not need to be verified.
## What Happens Without Verification
If the receiving wallet is not verified through Proof, the [`/order`](/build/trading-api/order/order) endpoint returns an error instead of a transaction when buying outcome tokens. Unverified wallets can still sell.
## Showing Quotes to Unverified Users
To let unverified users preview pricing before completing KYC, omit `userPublicKey` from the `/order` request. The API returns the quote without requiring verification.
This lets you build UX where users can browse markets and see prices, then get prompted to verify only when they attempt to execute a trade.
## Checking Verification Status
Use the [`/verify`](/build/proof-api/verify-address) endpoint to check whether a wallet is verified. Cache the response on your backend with a short TTL rather than calling `/verify` alongside every `/order` request.
See [Partner Integration](/build/proof/partner-integration) for the full integration flow, including deep linking, signature generation, and code examples.
## Geoblocking
KYC alone is not sufficient. Prediction markets are not permitted in all jurisdictions, so your application must also implement geoblocking to restrict access where local regulations apply. See [Prediction Market Compliance](/legal/prediction-market-compliance) for details.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Prediction Market Lifecycle
Source: https://pond.dflow.net/build/prediction-markets/market-lifecycle
How prediction markets progress from creation through settlement and finalization
A market’s status tells you whether users can trade, wait, or redeem, and nothing else.
Prediction markets move through a fixed lifecycle from creation to final settlement. A market’s **status** defines what actions users and builders can take at each stage.
Lifecycle order:
**`initialized` → `active` → `inactive` → `closed` → `determined` → `finalized`**
Markets may move forward through this sequence, and in some cases temporarily move backward from `inactive` to `active`.
The `inactive` status represents a paused state. A market can resume trading (`active`) or proceed toward closure (`closed`).
## Market Statuses
### Initialized
The market exists but trading has not started.
* Trading is not allowed
* No positions can be opened or closed
Transitions:
* → `active` when trading opens
### Active
The market is open for trading. This is the **only** status that allows trades.
Users can:
* Open new positions
* Reduce or close existing positions
Builders can:
* Execute trades through the Trade API
Transitions:
* → `inactive` if trading is paused
* → `closed` when trading ends
Only markets with `status: "active"` accept trades. Always check status before submitting orders.
### Inactive
Trading is paused.
* No trades can execute
* Existing positions remain unchanged
Transitions:
* → `active` if trading resumes
* → `closed` if trading ends permanently
### Closed
Trading has ended, but the outcome is not yet known.
* No trades allowed
* Outcome not yet determined
* Redemption not available
Transitions:
* → `determined` when the outcome is decided
### Determined
The outcome has been decided and written onchain.
* Trading remains disabled
* Winning outcome is known
* Redemption may be available, depending on funding
Transitions:
* → `finalized` once settlement completes
Markets with `status: "determined"` or `status: "finalized"` may allow redemption. Always check the `redemptionStatus` field to confirm availability.
### Finalized
The market has fully completed its lifecycle.
* Trading permanently disabled
* Outcome finalized
* Redemption available for winning positions
* No further changes
Transitions:
* None (final state)
## Querying Market Status
Builders read market status through the Prediction Market Metadata API. The `status` field is included in all market responses.
See the [Markets API reference](/metadata-api/markets/market) for details.
## Filtering by Status
Builders can filter markets by status across metadata endpoints:
* [**Markets API**](/metadata-api/markets/markets): Filter markets directly by status
* [**Events API**](/metadata-api/events/events): Filter events by the status of their markets
* [**Series API**](/metadata-api/series/series): Filter series by the status of their markets
Valid status values:
`initialized`, `active`, `inactive`, `closed`, `determined`, `finalized`
## Trading and Redemption Rules
Trading rules by status:
* **Active**: Trading allowed
* **Initialized / Inactive / Closed**: Trading not allowed
* **Determined / Finalized**: Trading disabled
Redemption rules:
* Redemption may be available in `determined` and `finalized`
* Always confirm via `redemptionStatus` before submitting redemption requests
## TL;DR
* Markets move from creation → trading → closure → settlement
* Only active markets allow trades
* Redemption happens after the outcome is determined
* Always check status and redemptionStatus before acting
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Parse Onchain Trades
Source: https://pond.dflow.net/build/prediction-markets/onchain-trade-parsing
How to parse prediction market trades, detect order fills, and calculate volume and fees onchain
This page explains how to parse prediction market trades onchain using the
Prediction Markets program IDL. The program account is:
`pReDicTmksnPfkfiz33ndSdbe2dY43KYPg4U2dbvHvb`.
Use this approach when you need:
* **Real-time fill detection**: detect order fills with minimal latency by
watching onchain events directly instead of polling the REST API.
* **Onchain analytics**: compute volume, fees, and fill rates from raw
program events.
If you only need user-facing trade history, use the
[Trades API](/build/metadata-api/trades/trades).
## Event Format
Events are emitted via the `EmitEvent` instruction. The discriminator is
`0xF0`, zero-padded to 8 bytes: `0xf000000000000000`.
The first byte after the discriminator (byte 8) is the `EventType`, which
tells you what kind of event was emitted:
| Value | EventType | Description |
| ------ | ---------- | -------------------------- |
| `0x01` | Market | Market-level event |
| `0x02` | UserOrder | User order lifecycle event |
| `0x03` | UserRedeem | User redemption event |
The remaining bytes after `EventType` are the event-specific data.
Decode the `UserOrderEvent` and `UserRedeemEvent` to determine order related info. Do not rely on raw instruction data, instruction formats can change without notice, but the event schema is stable.
## Order Lifecycle
When a user places an order, the program emits a `UserOrderEvent`
(`EventType` = `0x02`). The next byte (byte 9) is the
`userOrderEventType` field, which tracks the order lifecycle:
| Value | Type | Description |
| ------ | ------ | ------------------------------------------ |
| `0x01` | Open | Order placed and pending fill |
| `0x02` | Fill | Order (partially or fully) filled |
| `0x03` | Cancel | Order cancelled (e.g., FOK/IOC not filled) |
| `0x04` | Revert | Order reverted (e.g., slippage exceeded) |
The first event for a new order is always `Open`. Subsequent events (Fill,
Cancel, or Revert) are emitted in later block slots.
When a user redeems an outcome token, the program emits a `UserRedeemEvent`
(`EventType` = `0x03`) instead.
### Byte Layout Summary
| Byte(s) | Field | Description |
| ------- | ------------------------- | --------------------------------------------------------------------------- |
| 0–7 | Instruction discriminator | `0xf000000000000000` |
| 8 | `EventType` | `0x01`=Market, `0x02`=UserOrder, `0x03`=UserRedeem |
| 9 | `userOrderEventType` | UserOrderEvent only: `0x01`=Open, `0x02`=Fill, `0x03`=Cancel, `0x04`=Revert |
| 10+ | Event fields | Remaining event-specific data |
## Detecting Order Fills
To detect whether a specific order has been filled, follow this flow:
1. **Parse the Open event** from the transaction the user signed and submitted.
Extract the `userOrder` field, which is the onchain address of the order.
2. **Watch for subsequent transactions** that reference the same `userOrder`
address and emit a `UserOrderEvent` with `userOrderEventType` = `0x02` (Fill).
3. **Handle terminal states**: if you see `userOrderEventType` = `0x03` (Cancel)
or `0x04` (Revert), the order did not fill.
As long as you output to the user's wallet (rather than using the
`destinationWallet` parameter), the fill transaction will appear in the user's
transaction history. You can subscribe to a transaction stream for the user's
address and parse each transaction to detect fills in near real-time.
### Matching Opens to Fills
Use the `userOrder` field in `UserOrderEvent` to link related events.
* The Open event and its Fill event(s) share the same `userOrder` value.
* A single Open can have multiple Fill events (partial fills).
## Volume Calculation
In `UserOrderEvent`, use:
* `inputMint` / `inputAmount`
* `outputMint` / `outputAmount`
One of the mints will be a settlement mint (USDC or CASH), so you can sum the
corresponding amounts across Fill events to compute volume.
## Fee Calculation
`UserOrderEvent` includes:
* `feeMint`
* `feeAmount`
Fees are paid in the settlement mint, so summing `feeAmount` across Fill events
gives total fees.
## Relevant IDL Fields
From the IDL:
**UserOrderEvent**
| Field | Description |
| -------------------- | ------------------------------------------------------------------------ |
| `userOrderEventType` | Lifecycle stage (`0x01`=Open, `0x02`=Fill, `0x03`=Cancel, `0x04`=Revert) |
| `userOrder` | Onchain address of the order (links Open to Fill events) |
| `inputMint` | Mint of the token the user sent |
| `inputAmount` | Amount of input token |
| `outputMint` | Mint of the token the user received |
| `outputAmount` | Amount of output token |
| `feeMint` | Mint used for fees (settlement mint) |
| `feeAmount` | Fee amount in the fee mint |
**FillInstructionParams**
| Field | Description |
| ---------------------- | ------------------------------- |
| `consumedInputAmount` | Input consumed in this fill |
| `producedOutputAmount` | Output produced in this fill |
| `platformFeeAmount` | Platform fee taken in this fill |
## Related Pages
* [Prediction Market Data Model](/build/prediction-markets/prediction-market-data-model)
* [Prediction Market Fees and Rebates](/build/prediction-markets/prediction-market-fees)
* [Trades API](/build/metadata-api/trades/trades)
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Prediction Market Data Model
Source: https://pond.dflow.net/build/prediction-markets/prediction-market-data-model
How prediction market data is structured across events, markets, and trades
This page describes the core entities in the Prediction Markets API and how they
relate. All field names below come from
`build/metadata-api/openapi.json`.
## High-Level Model
Events group one or more markets. Each market has onchain accounts (mints and a
ledger), and produces orderbook and trade data. The API does not expose a
dedicated “Order” schema; order intent is represented in the orderbook payloads.
```mermaid theme={null}
flowchart TD
Event -->|contains| Market
Event -->|sources| SettlementSource
Market -->|accounts map to| MarketAccountInfo
Market -->|orderbook| Orderbook
Market -->|trades| Trade
```
## Example (Red Sox vs Yankees)
**[Event](#event-singleeventresponse)**: “Will the Boston Red Sox win the World Series?”\
**[Market](#market-singlemarketresponse)**: A single YES/NO market under that event.\
**[Orderbook](#orderbook)**: The current bid/ask ladders for that market.\
**[Trade](#trade-singletraderesponse)**: Executed trades for that market ticker.
In practice:
* You discover the **event** and its **markets**.
* You look up **market accounts** (yes/no mints, ledger).
* You pull **orderbook** and **trade** history by market ticker or mint.
## Trading Flow (Spot → Outcome Token)
The Trade API [`/order`](/build/trading-api/order/order) endpoint can trade
from any spot token to a prediction market outcome token. The transaction
always routes through the settlement mint as an intermediate step:
1. **Input Token → Settlement Mint**
2. **Settlement Mint → Outcome Token**
The `/order` response returns a single transaction that executes both swaps.
### Market Initialization Behavior
The Trading API automatically detects whether the market is initialized:
* **Initialized markets**: the two-step swap path executes directly.
* **Uninitialized markets**: the transaction includes on-demand market
tokenization before executing the swap path.
On-demand market tokenization incurs a small fee, which is included in the
transaction when trading into an uninitialized market.
### Checking Initialization Status (Optional)
You can check `isInitialized` in the market response from the
[Markets API](/build/metadata-api/markets/markets), but you
do not need to do this ahead of time, because the Trading API handles it automatically.
The `isInitialized` query parameter on the
[Events](/build/metadata-api/events/events),
[Markets](/build/metadata-api/markets/markets), and
[Series](/build/metadata-api/series/series) listing endpoints filters results
to markets that have already been tokenized through a DFlow trade. Markets that
are active on Kalshi but have not yet been traded through DFlow will have
`isInitialized = false` and will be excluded when you pass
`isInitialized=true`.
This is especially common with **short-duration markets** (e.g., 15-minute
crypto price markets) where initialization resets with each new market. If you
need to display all active markets, omit the `isInitialized` parameter.
## Entity Reference
### Event (SingleEventResponse)
| Field | Type | Notes |
| ------------------- | --------------- | ------------------------------ |
| `ticker` | string | Event ticker |
| `seriesTicker` | string | Series identifier |
| `title` | string | Event title |
| `subtitle` | string | Event subtitle |
| `competition` | string \| null | Competition name |
| `competitionScope` | string \| null | Scope of competition |
| `imageUrl` | string \| null | Image URL |
| `liquidity` | integer \| null | Aggregate liquidity |
| `openInterest` | integer \| null | Aggregate open interest |
| `volume` | integer \| null | Total volume |
| `volume24h` | integer \| null | 24h volume |
| `strikeDate` | integer \| null | Unix timestamp |
| `strikePeriod` | string \| null | Strike period label |
| `settlementSources` | array \| null | Settlement sources |
| `markets` | array \| null | Array of markets (if included) |
SettlementSource fields:
| Field | Type | Notes |
| ------ | ------ | ----------- |
| `name` | string | Source name |
| `url` | string | Source URL |
### Market (SingleMarketResponse)
| Field | Type | Notes |
| --------------------- | -------------- | --------------------- |
| `ticker` | string | Market ticker |
| `eventTicker` | string | Parent event ticker |
| `marketType` | string | Market type |
| `title` | string | Market title |
| `subtitle` | string | Market subtitle |
| `yesSubTitle` | string | YES outcome label |
| `noSubTitle` | string | NO outcome label |
| `openTime` | integer | Unix timestamp |
| `closeTime` | integer | Unix timestamp |
| `expirationTime` | integer | Unix timestamp |
| `status` | string | Market status |
| `result` | string | Resolution outcome |
| `volume` | integer | Market volume |
| `openInterest` | integer | Market open interest |
| `canCloseEarly` | boolean | Early close enabled |
| `earlyCloseCondition` | string \| null | Early close condition |
| `rulesPrimary` | string | Primary rules |
| `rulesSecondary` | string \| null | Secondary rules |
| `yesBid` | string \| null | Best bid (YES) |
| `yesAsk` | string \| null | Best ask (YES) |
| `noBid` | string \| null | Best bid (NO) |
| `noAsk` | string \| null | Best ask (NO) |
| `accounts` | object | Map of account info |
MarketAccountInfo fields:
| Field | Type | Notes |
| ------------------ | --------------- | ------------------- |
| `marketLedger` | string | Market ledger mint |
| `yesMint` | string | YES outcome mint |
| `noMint` | string | NO outcome mint |
| `isInitialized` | boolean | Account initialized |
| `redemptionStatus` | string \| null | Redemption state |
| `scalarOutcomePct` | integer \| null | Scalar outcome % |
### Trade (SingleTradeResponse)
| Field | Type | Notes |
| ----------------- | ------- | --------------------- |
| `tradeId` | string | Trade identifier |
| `ticker` | string | Market ticker |
| `price` | integer | Price (0-10000 scale) |
| `count` | integer | Quantity |
| `yesPrice` | integer | YES price |
| `noPrice` | integer | NO price |
| `yesPriceDollars` | string | YES price in dollars |
| `noPriceDollars` | string | NO price in dollars |
| `takerSide` | string | Buyer/seller side |
| `createdTime` | integer | Unix timestamp |
### Orderbook
Orderbook responses include a sequence number and bid ladders for YES and NO.
Each ladder is a map of **price strings** (4‑decimal probability) to **size
integers**.
| Field | Type | Notes |
| ---------- | ------- | --------------------- |
| `sequence` | integer | Monotonic sequence id |
| `yes_bids` | object | Map of price → size |
| `no_bids` | object | Map of price → size |
Example:
```json theme={null}
{
"no_bids": {
"0.0100": 2892941,
"0.0200": 9478,
"0.0300": 349205
},
"sequence": 4169465,
"yes_bids": {}
}
```
Use:
* `GET /api/v1/orderbook/{market_ticker}`
* `GET /api/v1/orderbook/by-mint/{mint_address}`
See the endpoint docs:
* [Orderbook by ticker](/build/metadata-api/orderbook/orderbook-by-ticker)
* [Orderbook by mint](/build/metadata-api/orderbook/orderbook-by-mint)
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Prediction Market Fees and Rebates
Source: https://pond.dflow.net/build/prediction-markets/prediction-market-fees
How prediction market fees and rebates are calculated
When using the DFlow Prediction Markets API, builders pay trading fees based on their aggregate outcome token trading volume. Fees apply to executed trades and scale with both price and contract size.
## How Fees Are Calculated
Fees for prediction market trades use a probability-weighted model.
The fee for a trade is calculated as:
`fees = roundup(0.07 × c × p × (1 − p)) + (0.01 × c × p × (1 − p))`
Where:
* `p` is the fill price.
* `c` is the number of contracts traded.
This model charges higher fees when outcomes are less certain and lower fees as
markets approach resolution.
## Fee Tiers
Builders move through fee tiers based on their rolling 30-day trading volume on outcome tokens via the Prediction Markets API.
Fee Schedule
| Tier | 30D Volume | Taker Fee Scale | Maker Fee Scale |
| -------- | ---------- | --------------- | --------------- |
| Frost | \< \$50M | 0.09 | 0.0225 |
| Glacier | \$50–150M | 0.0875 | 0.021875 |
| Steel | \$150–300M | 0.085 | 0.02125 |
| Obsidian | > \$300M | 0.08 | 0.02 |
Fee tiers are determined by total outcome token trading volume over the last 30 days.
## Rebate Program
Builders with more than \$100k in 30-day outcome token volume may qualify for the Prediction Markets API rebate program.
Eligible builders receive the greater of:
* 3% of gross applicable trading fees, or
* The marginal rebate amount defined by the VIP rebate schedule.
Rebates are calculated on aggregate trading volume across all applications using the Prediction Markets API on Solana, then distributed pro-rata based on each builder’s contribution.
Rebate eligibility is subject to approval by DFlow and may change at DFlow’s discretion.
| Tier | 30D Volume | Incremental Rebate |
| ----- | ---------- | ------------------------------ |
| VIP 0 | \< \$50M | No incremental rebate |
| VIP 1 | \$50–150M | 10% rebate on incremental fees |
| VIP 2 | \$150–300M | 20% rebate on incremental fees |
| VIP 3 | > \$300M | 30% rebate on incremental fees |
Only fees up to a **taker scale of 0.07** and **maker scale of 0.0175** are eligible for rebates.
## Rebate Example
If total aggregate outcome token volume across all partners reaches \$75M in a month:
Builders receive either:
* 3% of total applicable fees, or
* 10% on the \$25M increment above \$50M, distributed proportionally.
Whichever amount is larger is applied.
## Volume Tracking
DFlow tracks outcome token trading volume by API key.
To ensure correct tracking:
* Builders must include their API key on all Prediction Markets API requests.
* Only trades executed through the Prediction Markets API count toward volume.
See the [API Keys guide](/build/api-key) for details on generating and using API keys.
Volume thresholds for fee tiers and rebates are based on aggregate outcome token trading volume across Solana, not per application.
## Account Rent and Redemption
Most of the cost users see when trading prediction markets comes from Solana
account rent, not platform fees.
Prediction market trades create multiple onchain accounts, including outcome
token accounts and protocol-owned market accounts. Rent is paid (in SOL) when these
accounts are created.
### Winning positions
When a user redeems a winning outcome:
* The user’s outcome token account is closed.
* The rent for that token account is returned to the account specified by the [`outcomeAccountRentRecipient`](/build/trading-api/order/order#parameter-outcome-account-rent-recipient) parameter.
* Protocol-owned market accounts remain open and are not closed.
### Losing positions
If a user loses a bet:
* There is no redeem route for the losing outcome.
* The losing outcome token is worthless.
* The user can burn the losing outcome token to close the token account and
reclaim the rent for that account (from the account specified by the [`outcomeAccountRentRecipient`](/build/trading-api/order/order#parameter-outcome-account-rent-recipient) parameter).
Only user-owned token accounts can be closed and reclaimed. Protocol-owned
accounts are not closed.
On Solana, the account **payer** (who funds account creation) and the account
**owner** (who controls the account) are different concepts. Users may pay to
create protocol-owned accounts during a trade, but only the account owner can
close an account and reclaim its rent.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Introduction
Source: https://pond.dflow.net/build/proof-api/introduction
API for wallet verification and identity
Check if wallet addresses are verified
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Verify Address
Source: https://pond.dflow.net/build/proof-api/verify-address
GET /verify/{address}
Check if a wallet address has been verified
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Proof KYC Introduction
Source: https://pond.dflow.net/build/proof/introduction
Identity verification service linking verified identities to Solana wallets
Proof is an identity verification service on Solana. It enables partner applications to verify that a wallet belongs to a KYC'd individual without handling identity verification themselves.
## When Proof Is Required
Buying prediction market outcome tokens requires Proof verification. Spot trading does not require Proof. See [Understanding KYC for Prediction Markets](/build/prediction-markets/kyc) for details.
## High-Level Model
Proof connects three key entities: users, verified identities, and wallets. Users authenticate and verify their identity once, then link multiple wallets to that identity. Partner applications query the identity graph to check verification status.
```mermaid theme={null}
flowchart TD
User -->|authenticates| Session
User -->|completes| Verification
Verification -->|creates| VerifiedIdentity[Verified Identity]
VerifiedIdentity -->|links to| Wallet1[Wallet 1]
VerifiedIdentity -->|links to| Wallet2[Wallet 2]
VerifiedIdentity -->|links to| WalletN[Wallet N]
PartnerApp[Partner App] -->|queries| VerifiedIdentity
```
## Verified Information
Proof verifies the following information about users:
| Verified Information | Description |
| ------------------------- | --------------------------------------- |
| Name | Full legal name from government ID |
| Address | Residential address |
| Contact Information | Email address (used for authentication) |
| Government Identification | Government-issued ID document |
## Key Outcomes
### Identity Graph
Creates a mapping between verified identities and wallet addresses that can be queried by partner applications. This graph is the core data structure that enables verification across the ecosystem.
### Reduce Friction for Partner Apps
Allows apps to outsource identity verification while maintaining a seamless user experience. Partners redirect users to Proof, and users return verified, no need to build KYC infrastructure.
### Compliance
Helps partner applications meet regulatory requirements by providing verified wallet ownership data. When a partner queries a wallet, they get a clear verification status they can use for compliance decisions.
### One-Time Verification
Users verify once and can use their verified identity across all partner applications. This reduces friction for users and increases conversion for partners.
## What Proof Delivers
### Authentication
* Email-based authentication with one-time codes
* Session persistence across visits
### Identity Verification
* Document verification (government-issued ID)
* Biometric verification (selfie matching / liveness check)
* Clear status communication (pending, verified, failed)
### Wallet Management
* Link multiple wallets to a single verified identity
* Cryptographic proof of wallet ownership (signature verification)
* Optional wallet labels for organization
* Remove wallets when needed
* Audit trail of wallet changes
## Next Steps
Understand the verification flows for different user types.
Learn how to integrate Proof into your application.
Explore the API endpoints for verification and wallet management.
Read the conceptual overview of Proof.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Proof KYC Partner Integration
Source: https://pond.dflow.net/build/proof/partner-integration
How to integrate Proof into your application with deep linking and the verification API
This page describes how partner applications can integrate with Proof to verify users. Partners can redirect users to Proof for verification and query the Proof API to check verification status.
## Integration Overview
```mermaid theme={null}
flowchart LR
subgraph partner [Partner App]
A[User Action] --> B[Check Verification]
B --> C{Verified?}
C -->|No| D[Redirect to Proof]
C -->|Yes| E[Allow Action]
end
subgraph proof [Proof]
D --> F[User Verifies]
F --> G[Redirect Back]
end
G --> B
```
## Deep Linking
Partners can redirect users to Proof with pre-populated data to streamline the verification flow. When the user completes verification, they are redirected back to your application.
### Deep Link Parameters
| Parameter | Required | Description |
| -------------- | -------- | --------------------------------------------------------- |
| `wallet` | Yes | The Solana wallet address to link |
| `signature` | Yes | Pre-signed ownership proof (base58 encoded) |
| `timestamp` | Yes | Unix timestamp in milliseconds when signature was created |
| `redirect_uri` | Yes | URL to redirect the user after verification |
| `email` | No | Email address to prefill in the authentication step |
| `projectId` | No | Your project identifier for tracking |
**Redirect URIs must use `https:` or `chrome-extension:` schemes.** Custom URL schemes (e.g. `myapp://`) are not supported and the redirect will not fire. Native mobile apps should use [universal links](https://developer.apple.com/ios/universal-links/) (iOS) or [app links](https://developer.android.com/training/app-links) (Android), which use `https:` URLs that deep link into your app.
### Constructing a Deep Link
Build the deep link URL with query parameters:
```
https://dflow.net/proof?wallet={address}&signature={signature}×tamp={timestamp}&redirect_uri={encodedRedirectUri}&email={encodedEmail}
```
### Generating the Signature
The user must sign a message proving wallet ownership. The message format is:
```
Proof KYC verification: {timestamp}
```
Where `{timestamp}` is the Unix timestamp in **milliseconds** (13 digits).
### Example: Creating a Deep Link
```typescript theme={null}
import { Connection, PublicKey } from "@solana/web3.js";
import bs58 from "bs58";
async function createProofDeepLink(
wallet: { publicKey: PublicKey; signMessage: (message: Uint8Array) => Promise },
redirectUri: string
): Promise {
// Generate timestamp in milliseconds
const timestamp = Date.now();
// Create the message to sign
const message = `Proof KYC verification: ${timestamp}`;
const messageBytes = new TextEncoder().encode(message);
// Request signature from wallet
const signatureBytes = await wallet.signMessage(messageBytes);
const signature = bs58.encode(signatureBytes);
// Build the deep link URL
const params = new URLSearchParams({
wallet: wallet.publicKey.toBase58(),
signature,
timestamp: timestamp.toString(),
redirect_uri: redirectUri,
});
return `https://dflow.net/proof?${params.toString()}`;
}
// Usage
const deepLink = await createProofDeepLink(wallet, "https://yourapp.com/callback");
window.location.href = deepLink;
```
### Handling the Return
When the user completes verification (or cancels), they are redirected to your `redirect_uri`. Query the verification API to confirm their status.
When verification succeeds, Proof also sends an "Identity Verification Complete" email to the user.
```typescript theme={null}
async function handleProofCallback(walletAddress: string): Promise {
const response = await fetch(
`https://proof.dflow.net/verify/${walletAddress}`
);
const { verified } = await response.json();
return verified;
}
```
## Verification API
The verification API lets you check if a wallet address is linked to a verified identity. This is a public endpoint that does not require authentication.
### Endpoint
```
GET https://proof.dflow.net/verify/{address}
```
### Parameters
| Parameter | Location | Type | Description |
| --------- | -------- | ------ | ---------------------------------------- |
| `address` | path | string | Solana wallet address (32-44 characters) |
### Response
```json theme={null}
{
"verified": true
}
```
| Field | Type | Description |
| ---------- | ------- | --------------------------------------------------- |
| `verified` | boolean | Whether the wallet is linked to a verified identity |
### Example: Checking Verification Status
```typescript theme={null}
async function isWalletVerified(address: string): Promise {
const response = await fetch(
`https://proof.dflow.net/verify/${address}`
);
if (!response.ok) {
throw new Error(`Failed to check verification: ${response.status}`);
}
const { verified } = await response.json();
return verified;
}
// Usage
const walletAddress = "DFlow1111111111111111111111111111111111111";
const verified = await isWalletVerified(walletAddress);
if (verified) {
console.log("Wallet is verified");
} else {
console.log("Wallet is not verified");
}
```
### Example: Gating Features
```typescript theme={null}
async function handleRestrictedAction(walletAddress: string) {
const verified = await isWalletVerified(walletAddress);
if (!verified) {
// Redirect to Proof for verification
const redirectUri = encodeURIComponent(window.location.href);
window.location.href = `https://dflow.net/proof?redirect_uri=${redirectUri}`;
return;
}
// User is verified, proceed with action
await performRestrictedAction();
}
```
## Integration Flow
Here's a complete integration flow combining deep linking and the verification API:
```mermaid theme={null}
sequenceDiagram
participant User
participant PartnerApp as Partner App
participant Wallet
participant Proof
User->>PartnerApp: Initiate restricted action
PartnerApp->>Proof: GET /verify/{address}
Proof->>PartnerApp: { verified: false }
PartnerApp->>User: Request wallet signature
User->>Wallet: Sign verification message
Wallet->>User: Signature
User->>PartnerApp: Provide signature
PartnerApp->>Proof: Redirect with deep link
Note over Proof: User completes verification
Proof->>PartnerApp: Redirect to redirect_uri
PartnerApp->>Proof: GET /verify/{address}
Proof->>PartnerApp: { verified: true }
PartnerApp->>User: Allow restricted action
```
## Best Practices
### Cache Verification Status
Verification status is stable once a user is verified. Consider caching the result to reduce API calls:
```typescript theme={null}
const verificationCache = new Map();
async function isWalletVerified(address: string): Promise {
// Check cache first
if (verificationCache.has(address)) {
return verificationCache.get(address)!;
}
const response = await fetch(
`https://proof.dflow.net/verify/${address}`
);
const { verified } = await response.json();
// Cache verified status (don't cache unverified as it may change)
if (verified) {
verificationCache.set(address, true);
}
return verified;
}
```
### Getting Prediction Market Order Quotes for Unverified Users
To show order quotes to unverified users, omit `userPublicKey` from [`/order`](/build/trading-api/order/order) requests.
### Handle Edge Cases
* **Signature expiration**: Generate fresh signatures close to redirect time
* **User cancellation**: Handle cases where users return without completing verification
* **Network errors**: Implement retry logic for API calls
### Security Considerations
* Always verify wallet ownership server-side when performing sensitive actions
* Do not trust client-side verification status alone for security-critical operations
* Use HTTPS for all API calls and redirects
## API Reference
For complete API documentation, see the [Proof API Reference](/build/proof-api/introduction):
* [Verify Address](/build/proof-api/verify-address) — Check if a wallet is verified
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Proof KYC User Journeys
Source: https://pond.dflow.net/build/proof/user-journeys
Verification flows for direct users, partner app users, and returning users
This page describes the three primary user journeys through Proof:
* [New users visiting directly](#new-user-direct).
* [New users redirected from a partner app](#new-user-from-partner-app).
* [Returning users](#returning-user).
## New User (Direct)
```mermaid theme={null}
flowchart LR
subgraph direct [New User - Direct]
direction LR
D1[Visit Proof] --> D2[Authenticate]
D2 --> D3[Verify Identity]
D3 --> D4[Link Wallets]
D4 --> D5[Manage Wallets]
end
```
```mermaid theme={null}
flowchart TD
subgraph direct [New User - Direct]
D1[Visit Proof] --> D2[Authenticate]
D2 --> D3[Verify Identity]
D3 --> D4[Link Wallets]
D4 --> D5[Manage Wallets]
end
```
Users who visit Proof directly to verify their identity and link wallets.
### Flow
1. **User visits Proof directly**
* User navigates to the Proof application
* Landing page explains the verification process
2. **Authenticates with email**
* User enters their email address
* Proof sends a one-time code
* User enters the code to authenticate
3. **Completes identity verification**
* User uploads a government-issued ID
* User completes a liveness check (selfie matching)
* Verification processes (may take time)
* User sees status: pending, verified, or failed
* On successful verification, Proof sends an "Identity Verification Complete" email
4. **Links one or more wallets**
* User connects a Solana wallet
* User signs a message to prove ownership
* Proof verifies the signature and links the wallet
* User can optionally add a label
5. **Manages linked wallets over time**
* User can view all linked wallets
* User can add new wallets
* User can update wallet labels
* User can remove wallets
### Sequence Diagram
```mermaid theme={null}
sequenceDiagram
participant User
participant Proof
participant Wallet
User->>Proof: Visit Proof
User->>Proof: Enter email
Proof->>User: Send OTP
User->>Proof: Enter OTP
Proof->>User: Authenticated
User->>Proof: Upload ID
User->>Proof: Complete liveness check
Proof->>User: Verification status
User->>Wallet: Connect wallet
Wallet->>User: Connected
User->>Proof: Request signature message
Proof->>User: Signature message
User->>Wallet: Sign message
Wallet->>User: Signature
User->>Proof: Submit signature
Proof->>User: Wallet linked
```
## New User (From Partner App)
```mermaid theme={null}
flowchart LR
subgraph partner [New User - Partner App]
direction LR
P1[Partner Redirects] --> P2[Authenticate]
P2 --> P3[Verify Identity]
P3 --> P4[Auto-Link Wallet]
P4 --> P5[Redirect Back]
end
```
Users redirected to Proof from a partner application that requires verification.
### Flow
1. **User initiates action in partner app**
* User attempts an action requiring verification
* Partner app detects user is not verified
2. **Partner app redirects to Proof**
* Partner app generates a deep link with:
* Wallet address to link
* Pre-signed ownership proof (signature)
* Return URL for post-verification redirect
* User is redirected to Proof
3. **User authenticates**
* User enters their email address
* Proof sends a one-time code
* User enters the code to authenticate
4. **User completes identity verification**
* User uploads a government-issued ID
* User completes a liveness check
* Verification processes
* On successful verification, Proof sends an "Identity Verification Complete" email
5. **Wallet is automatically linked**
* Proof verifies the pre-signed ownership proof
* Wallet is linked without additional user action
6. **User is redirected back to partner app**
* Proof redirects to the provided return URL
* Partner app can now query verification status
### Sequence Diagram
```mermaid theme={null}
sequenceDiagram
participant User
participant PartnerApp as Partner App
participant Proof
participant Wallet
User->>PartnerApp: Initiate action
PartnerApp->>User: Request wallet signature
User->>Wallet: Sign message
Wallet->>User: Signature
User->>PartnerApp: Provide signature
PartnerApp->>Proof: Redirect with wallet + signature + returnUrl
User->>Proof: Enter email
Proof->>User: Send OTP
User->>Proof: Enter OTP
Proof->>User: Authenticated
User->>Proof: Upload ID
User->>Proof: Complete liveness check
Proof->>User: Verified
Proof->>Proof: Verify signature
Proof->>Proof: Link wallet
Proof->>PartnerApp: Redirect to returnUrl
PartnerApp->>Proof: Query verification status
Proof->>PartnerApp: Verified
```
## Returning User
```mermaid theme={null}
flowchart LR
subgraph returning [Returning User]
direction LR
R1[Visit or Redirect] --> R2[Authenticate]
R2 --> R3[Skip Verification]
R3 --> R4[Manage or Redirect]
end
```
```mermaid theme={null}
flowchart TD
subgraph returning [Returning User]
R1[Visit or Redirect] --> R2[Authenticate]
R2 --> R3[Skip Verification]
R3 --> R4[Manage or Redirect]
end
```
Users who have already completed verification and return to Proof.
### Flow
1. **User visits Proof or is redirected from partner app**
* User navigates directly to Proof, or
* Partner app redirects user to Proof
2. **Authenticates with email**
* User enters their email address
* Proof sends a one-time code
* User enters the code to authenticate
3. **Skips verification (already complete)**
* Proof recognizes the user is already verified
* No additional verification required
4. **Manages wallets or is redirected back**
* If direct visit: User can manage wallets
* If from partner: User is redirected back with existing wallet linked, or can link a new wallet
### Sequence Diagram
```mermaid theme={null}
sequenceDiagram
participant User
participant Proof
participant PartnerApp as Partner App
alt Direct Visit
User->>Proof: Visit Proof
User->>Proof: Authenticate
Proof->>User: Already verified
User->>Proof: Manage wallets
else From Partner App
PartnerApp->>Proof: Redirect with wallet + signature
User->>Proof: Authenticate
Proof->>User: Already verified
Proof->>Proof: Link wallet if new
Proof->>PartnerApp: Redirect to returnUrl
end
```
## Verification States
Throughout these journeys, users may encounter different verification states:
| State | Description | Next Action |
| ------------ | --------------------------------- | ---------------------------- |
| `unverified` | User has not started verification | Begin verification |
| `pending` | Verification is processing | Wait for completion |
| `verified` | Verification successful | Link wallets or use services |
| `failed` | Verification unsuccessful | Contact support or retry |
## Related Pages
* [Partner Integration](/build/proof/partner-integration) — How to redirect users and query verification status
* [Proof API Reference](/build/proof-api/introduction) — API endpoints for all operations
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Authenticating Requests
Source: https://pond.dflow.net/build/recipes/api-keys
How to authenticate requests with DFlow API keys
During development, you can use the [developer endpoints](/build/endpoints) without an API key. For production use, you'll need an [API key](/build/api-key) to avoid rate limits.
## Using Your API Key
Include your API key in all requests to the APIs by setting the `x-api-key` header.
All production deployments must use an API key, otherwise you will be rate limited.
For GET requests, include the API key in the request headers:
```typescript theme={null}
const API_KEY = process.env.DFLOW_API_KEY; // or your API key
const API_BASE_URL = "https://dev-quote-api.dflow.net";
const queryParams = new URLSearchParams();
queryParams.append("inputMint", SOL);
queryParams.append("outputMint", USDC);
queryParams.append("amount", amount.toString());
queryParams.append("slippageBps", slippageBps.toString());
queryParams.append("userPublicKey", keypair.publicKey.toBase58());
const response = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`,
{
headers: {
"x-api-key": API_KEY,
},
}
).then((x) => x.json());
```
For POST requests, include the API key alongside other headers:
```typescript theme={null}
const API_KEY = process.env.DFLOW_API_KEY; // or your API key
const API_BASE_URL = "https://dev-quote-api.dflow.net";
const response = await fetch(`${API_BASE_URL}/submit-intent`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": API_KEY,
},
body: JSON.stringify({
quoteResponse: intentData,
signedOpenTransaction: Buffer.from(openTransaction.serialize()).toString(
"base64"
),
}),
});
const submitIntentData = await response.json();
```
## WebSocket Authentication
WebSocket connections require both an API key and a WebSocket endpoint. Apply for credentials at
[https://pond.dflow.net/build/api-key](https://pond.dflow.net/build/api-key).
When using WebSockets, include your API key in the `x-api-key` header rather than a URL query parameter.
```typescript theme={null}
import "dotenv/config";
const API_KEY = process.env.DFLOW_API_KEY;
const WS_URL = process.env.DFLOW_PREDICTION_MARKETS_WS_URL;
if (!WS_URL || !API_KEY) {
throw new Error(
"Missing websocket credentials. Set DFLOW_PREDICTION_MARKETS_WS_URL and DFLOW_API_KEY."
);
}
const ws = new WebSocket(WS_URL, {
headers: {
"x-api-key": API_KEY,
},
});
```
## Security Best Practices
* Store your API key securely using environment variables.
* Never commit API keys to version control.
* Rotate your API key if it's ever exposed.
## Getting Help
If you need an API key or have questions about rate limits, [reach out to us](/build/api-key).
## API Routes
* [GET /order](/build/trading-api/order/order)
* [POST /submit-intent](/build/trading-api/declarative/submit)
## Cookbook Repository
This recipe, along with many more, is available in the [DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Close Outcome Token Accounts
Source: https://pond.dflow.net/build/recipes/prediction-markets/close-outcome-token-accounts
How to close empty outcome token accounts to reclaim rent
On Solana, accounts must hold a rent-exempt balance (lamports) to exist. When you close an empty token account, those lamports are returned to the destination you specify. If you set [`outcomeAccountRentRecipient`](/build/trading-api/order/order#parameter-outcome-account-rent-recipient) when requesting an order, retrieve that value from your stored order params and reuse it as the close destination. Otherwise, choose any destination (typically the user's wallet).
Closing a token account is a standard SPL Token action. DFlow does not provide a dedicated endpoint for this.
After losing a position, the outcome token account is worthless. Close the empty
account to reclaim the rent lamports.
Decide where the reclaimed rent should go. If your app set
[`outcomeAccountRentRecipient`](/build/trading-api/order/order#parameter-outcome-account-rent-recipient) when creating the order, use that address.
```typescript theme={null}
const userPublicKey = keypair.publicKey.toBase58();
// Optional: reuse the address you set when creating the order.
// If you did not set one, default to the user's wallet.
const outcomeAccountRentRecipient =
storedOrderParams?.outcomeAccountRentRecipient ?? null;
const rentDestination = outcomeAccountRentRecipient ?? userPublicKey;
```
A token account must be empty to close. If it still has a balance, burn the
remaining outcome tokens and then close the account to reclaim rent.
```typescript theme={null}
import {
Connection,
PublicKey,
Transaction,
sendAndConfirmTransaction,
} from "@solana/web3.js";
import {
getAccount,
createBurnInstruction,
createCloseAccountInstruction,
} from "@solana/spl-token";
const connection = new Connection(SOLANA_RPC_URL, "confirmed");
const owner = keypair; // signer and token account owner
const tokenAccount = new PublicKey("OUTCOME_TOKEN_ACCOUNT");
const outcomeMint = new PublicKey("OUTCOME_TOKEN_MINT");
const rentRecipient = new PublicKey(rentDestination);
const account = await getAccount(connection, tokenAccount);
const instructions = [];
if (account.amount > 0n) {
instructions.push(
createBurnInstruction(
tokenAccount,
outcomeMint,
owner.publicKey,
account.amount
)
);
}
instructions.push(
createCloseAccountInstruction(
tokenAccount,
rentRecipient,
owner.publicKey
)
);
const tx = new Transaction().add(...instructions);
await sendAndConfirmTransaction(connection, tx, [owner]);
```
## KYC Requirements
Prediction market applications must use [Proof](/build/proof/introduction) to meet Kalshi compliance requirements.
## API Routes
This recipe does not call DFlow APIs. It uses a Solana RPC endpoint and the SPL
Token program.
## Cookbook Repository
This recipe, along with many more, is available in the
[DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can
clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Decrease a Position
Source: https://pond.dflow.net/build/recipes/prediction-markets/decrease-position
How to decrease a prediction market position
During development, you can use the [developer endpoints](/build/endpoints)
without an API key. For production use, you'll need an
[API key](/build/api-key) to avoid rate limits.
Decrease a position by trading **YES** or **NO** outcome tokens back into a
settlement stablecoin. Submit a trade, and the system opens a reduce order,
routes to offchain liquidity, and settles onchain.
Start with the outcome mint you want to reduce. If you need to find outcome
mints first, use
[Discover Prediction Markets](/build/recipes/prediction-markets/discover-markets).
Request a trade from the outcome token into a settlement mint using
`/order`. This opens a reduce order and writes your **limit price** and **side**
(YES or NO) into the **Reduce Order Escrow** account while escrowes your outcome
tokens.
```typescript theme={null}
const API_BASE_URL = "https://dev-quote-api.dflow.net";
const API_KEY = process.env.DFLOW_API_KEY; // Optional
const outcomeMint = "OUTCOME_TOKEN_MINT_ADDRESS";
const settlementMint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; // USDC
const amount = 5_000_000; // 5 outcome tokens (6 decimals)
const queryParams = new URLSearchParams();
queryParams.append("inputMint", outcomeMint);
queryParams.append("outputMint", settlementMint);
queryParams.append("amount", amount.toString());
queryParams.append("userPublicKey", keypair.publicKey.toBase58());
const headers: HeadersInit = {};
if (API_KEY) {
headers["x-api-key"] = API_KEY;
}
const orderResponse = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`,
{ headers }
).then((x) => x.json());
```
Sign the transaction returned by `/order` and submit it to Solana.
```typescript theme={null}
const transactionBuffer = Buffer.from(orderResponse.transaction, "base64");
const transaction = VersionedTransaction.deserialize(transactionBuffer);
transaction.sign([keypair]);
const signature = await connection.sendTransaction(transaction);
```
Poll `/order-status` for async orders. This returns fills and the final
status.
```typescript theme={null}
const statusResponse = await fetch(
`${API_BASE_URL}/order-status?signature=${signature}`,
{ headers }
).then((x) => x.json());
console.log(statusResponse.status, statusResponse.fills);
```
You do not call a separate endpoint to fill the order. The settlement authority
reads your limit price and side from **Reduce Order Escrow**, submits a limit
IOC to offchain liquidity, and settles onchain. Depending on reserve balance,
the system follows one of two paths:
When reserves are balanced, the order settles immediately. Unused outcome tokens
are refunded, platform fees are transferred, and stablecoins move from the
**Settlement Vault** to your wallet.
When reserves are not balanced, the order fills without immediate settlement.
Unused outcome tokens are refunded. Later, when reserves rebalance, the
settlement authority completes settlement, transfers stablecoins to your wallet,
and pays platform fees.
A limit IOC (Immediate‑Or‑Cancel) order executes immediately at the limit
price (or better) for whatever size is available right now. Any unfilled
portion is canceled instead of resting on the book.
## KYC Requirements
Prediction market applications must use [Proof](/build/proof/introduction) to meet Kalshi compliance requirements.
## API Routes
* [GET /order](/build/trading-api/order/order)
* [GET /order-status](/build/trading-api/order/order-status)
## Cookbook Repository
This recipe, along with many more, is available in the
[DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can
clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Discover Prediction Markets
Source: https://pond.dflow.net/build/recipes/prediction-markets/discover-markets
How to discover prediction markets and outcome tokens
During development, you can use the [developer endpoints](/build/endpoints)
without an API key. For production use, you'll need an
[API key](/build/api-key) to avoid rate limits.
Use the Metadata API to discover markets and map [outcome token](/learn/prediction-markets#outcome-tokens)
mints for trading.
## Get Events with Nested Markets
You get **events** (real-world questions) and include their nested markets so
you can read outcome mints from the `accounts` field. If you need the data
model, review [Event fields](/build/prediction-market-data-model#event-singleeventresponse).
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/events?withNestedMarkets=true&limit=200`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to get events");
}
const data = await response.json();
const events = data.events;
events.forEach((event: any) => {
console.log("Event:", {
ticker: event.ticker,
title: event.title,
subtitle: event.subtitle,
seriesTicker: event.seriesTicker,
});
if (event.markets && event.markets.length > 0) {
event.markets.forEach((market: any) => {
const accountValues = Object.values(market.accounts);
console.log(" Market:", {
ticker: market.ticker,
title: market.title,
status: market.status,
accounts: accountValues.map((account: any) => ({
yesMint: account.yesMint,
noMint: account.noMint,
})),
});
});
}
});
```
## Filter Events by Market Status
Filter events to focus on markets that match a given **status** (for
example, active vs. initialized). If you need the full status flow, see
[Prediction Market Lifecycle](/build/market-lifecycle).
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/events?withNestedMarkets=true&status=active&limit=200`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to get events");
}
const data = await response.json();
const events = data.events;
events.forEach((event: any) => {
if (event.markets && event.markets.length > 0) {
event.markets.forEach((market: any) => {
const accountValues = Object.values(market.accounts);
console.log("Market:", {
ticker: market.ticker,
title: market.title,
status: market.status,
accounts: accountValues.map((account: any) => ({
yesMint: account.yesMint,
noMint: account.noMint,
})),
});
});
}
});
```
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/events?withNestedMarkets=true&status=initialized&limit=200`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to get events");
}
const data = await response.json();
const events = data.events;
events.forEach((event: any) => {
if (event.markets && event.markets.length > 0) {
event.markets.forEach((market: any) => {
const accountValues = Object.values(market.accounts);
console.log("Market:", {
ticker: market.ticker,
title: market.title,
status: market.status,
accounts: accountValues.map((account: any) => ({
yesMint: account.yesMint,
noMint: account.noMint,
})),
});
});
}
});
```
## Get All Markets for a Specific Asset
If you know the asset you want (e.g., Bitcoin, SOL), the fastest approach is
to query the events endpoint directly with the `seriesTickers` parameter. Each
asset has a root series ticker (e.g., `KXBTC` for Bitcoin, `KXSOL` for SOL)
that covers all market types for that asset.
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
// Use the root series ticker for the asset (e.g., KXBTC for Bitcoin)
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/events?withNestedMarkets=true&seriesTickers=KXBTC&status=active`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to get events");
}
const data = await response.json();
const events = data.events;
events.forEach((event: any) => {
console.log("Event:", {
ticker: event.ticker,
title: event.title,
});
if (event.markets && event.markets.length > 0) {
event.markets.forEach((market: any) => {
const accountValues = Object.values(market.accounts);
console.log(" Market:", {
ticker: market.ticker,
title: market.title,
status: market.status,
accounts: accountValues.map((account: any) => ({
yesMint: account.yesMint,
noMint: account.noMint,
})),
});
});
}
});
```
If you don't know the series ticker for an asset, use the series endpoint
with a category and tag to find it first. For example,
`/api/v1/series?category=Crypto&tags=SOL` returns all series tickers that
start with `KXSOL`. You can then pass those tickers to the events endpoint.
For broader discovery without a specific asset in mind, use the categories
and tags approach below.
## Filter Events by Categories and Tags
Use tags to find relevant **series** (event templates) and then get events
for those series. This keeps discovery focused without hardcoding tickers.
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/tags_by_categories`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to get tags by categories");
}
const data = (await response.json()) as { tagsByCategories: Record };
const tagsByCategories = data.tagsByCategories;
Object.entries(tagsByCategories).forEach(
([category, tags]: [string, any]) => {
const tagList = Array.isArray(tags) ? tags.join(", ") : String(tags ?? "");
console.log(`Tags for ${category}: ${tagList}`);
}
);
```
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const selectedCategory = "Sports";
const selectedTag = "Football";
const responseByCategory = await fetch(
`${METADATA_API_BASE_URL}/api/v1/series?category=${selectedCategory}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
const dataByCategory = await responseByCategory.json();
const categorizedSeriesTickers = dataByCategory.series.map((s: any) => s.ticker);
const responseByTag = await fetch(
`${METADATA_API_BASE_URL}/api/v1/series?tags=${selectedTag}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!responseByTag.ok) {
throw new Error("Failed to get series");
}
const dataByTag = await responseByTag.json();
const taggedSeriesTickers = dataByTag.series.map((s: any) => s.ticker);
const selectedTags = "Football,Soccer";
const responseWithBoth = await fetch(
`${METADATA_API_BASE_URL}/api/v1/series?category=${selectedCategory}&tags=${selectedTags}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
const dataWithBoth = await responseWithBoth.json();
const filteredSeries = dataWithBoth.series;
const seriesTickers = filteredSeries.map((s: any) => s.ticker);
```
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const selectedSeriesTicker = seriesTickers[0];
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/events?seriesTickers=${selectedSeriesTicker}&withNestedMarkets=true&limit=100`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
const multipleSeriesTickers = seriesTickers.slice(0, 3).join(",");
const responseMultiple = await fetch(
`${METADATA_API_BASE_URL}/api/v1/events?seriesTickers=${multipleSeriesTickers}&withNestedMarkets=true&limit=100`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to get events by series");
}
const data = await response.json();
const filteredEvents = data.events;
filteredEvents.forEach((event: any) => {
console.log("Event:", {
ticker: event.ticker,
title: event.title,
subtitle: event.subtitle,
seriesTicker: event.seriesTicker,
});
if (event.markets && event.markets.length > 0) {
event.markets.forEach((market: any) => {
const accountValues = Object.values(market.accounts);
console.log(" Market:", {
ticker: market.ticker,
title: market.title,
status: market.status,
accounts: accountValues.map((account: any) => ({
yesMint: account.yesMint,
noMint: account.noMint,
})),
});
});
}
});
```
## Review API Responses
Use event and series responses to extract outcome mints and filter markets.
If you only need outcome mints, you can skip to the `accounts` map in each
market object.
### Events Response
You receive event metadata and nested markets (when `withNestedMarkets=true`),
including `yesMint` and `noMint` in market accounts.
### Tags by Categories Response
You receive a map of categories to tag arrays, which you use to filter series.
### Series Response
You receive series metadata, including ticker, title, category, tags, and
frequency.
## KYC Requirements
Prediction market applications must use [Proof](/build/proof/introduction) to meet Kalshi compliance requirements.
## API Routes
* [GET /api/v1/events](/build/metadata-api/events/events)
* [GET /api/v1/tags\_by\_categories](/build/metadata-api/tags/tags-by-categories)
* [GET /api/v1/series](/build/metadata-api/series/series)
## Cookbook Repository
This recipe, along with many more, is available in the
[DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can
clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Handle Fees
Source: https://pond.dflow.net/build/recipes/prediction-markets/fees-and-settlement
How to handle prediction market fees
During development, you can use the [developer endpoints](/build/endpoints)
without an API key. In production, use an [API key](/build/api-key) so volume
is tracked for fee tiers and rebates. If you use dev endpoints without a key,
your volume is not counted.
You include fees in prediction market trades and track fee tiers by volume. If
you need the full fee math, use the
[Fee Formula](/build/prediction-markets/prediction-market-fees#how-fees-are-calculated) section.
You pay a probability‑weighted fee based on price, size, and tier. Review
the [Fee Formula](/build/prediction-markets/prediction-market-fees#how-fees-are-calculated) and
[Fee Tiers](/build/prediction-markets/prediction-market-fees#fee-tiers) before you set pricing
expectations.
```typescript theme={null}
// Example fee estimation (not a quote).
// scale = tier fee coefficient
// p = fill price in probability terms (0.0 - 1.0)
// c = contracts traded
const scale = 0.09; // Example: Frost tier taker scale
const p = 0.62; // 62% implied probability
const c = 100; // 100 contracts
const fee = scale * p * (1 - p) * c;
console.log(`Estimated fee: ${fee.toFixed(4)} contracts`);
```
You qualify for rebates once you pass volume thresholds. Use the
[Rebate Program](/build/prediction-markets/prediction-market-fees#rebate-program) and
[Rebate Example](/build/prediction-markets/prediction-market-fees#rebate-example) to estimate
your effective fee rate.
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const API_KEY = process.env.DFLOW_API_KEY;
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/trades?limit=200`,
{
headers: {
"Content-Type": "application/json",
"x-api-key": API_KEY ?? "",
},
}
);
if (!response.ok) {
throw new Error("Failed to fetch trades");
}
const data = await response.json();
const trades = data.trades ?? [];
// Approximate notional = count * priceProbability (price/10000)
const notional = trades.reduce((sum: number, trade: any) => {
const p = Number(trade.price) / 10000;
return sum + p * Number(trade.count);
}, 0);
console.log(`Approx 30D notional volume: ${notional}`);
```
## KYC Requirements
Prediction market applications must use [Proof](/build/proof/introduction) to meet Kalshi compliance requirements.
## API Routes
* [GET /api/v1/trades](/build/metadata-api/trades/trades)
## Cookbook Repository
This recipe, along with many more, is available in the
[DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can
clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Increase a Position
Source: https://pond.dflow.net/build/recipes/prediction-markets/increase-position
How to increase a prediction market position
During development, you can use the [developer endpoints](/build/endpoints)
without an API key. For production use, you'll need an
[API key](/build/api-key) to avoid rate limits.
Increase a position by trading a stablecoin into a **YES** or **NO**
outcome token. Submit a trade, and the system opens an order, routes to
offchain liquidity, and settles onchain.
Start with the outcome mint you want to increase. If you need to find
outcome mints first, use
[Discover Prediction Markets](/build/recipes/prediction-markets/discover-markets).
Request a trade from a stablecoin into the outcome token using `/order`.
This opens an increase order and writes your **limit price** and **side**
(YES or NO) into the **User Order Escrow** account while escrowes your
stablecoin (USDC or CASH).
```typescript theme={null}
const API_BASE_URL = "https://dev-quote-api.dflow.net";
const API_KEY = process.env.DFLOW_API_KEY; // Optional
const inputMint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; // USDC
const outcomeMint = "OUTCOME_TOKEN_MINT_ADDRESS";
const amount = 25_000_000; // 25 USDC (6 decimals)
const queryParams = new URLSearchParams();
queryParams.append("inputMint", inputMint);
queryParams.append("outputMint", outcomeMint);
queryParams.append("amount", amount.toString());
queryParams.append("userPublicKey", keypair.publicKey.toBase58());
const headers: HeadersInit = {};
if (API_KEY) {
headers["x-api-key"] = API_KEY;
}
const orderResponse = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`,
{ headers }
).then((x) => x.json());
```
Sign the transaction returned by `/order` and submit it to Solana.
```typescript theme={null}
const transactionBuffer = Buffer.from(orderResponse.transaction, "base64");
const transaction = VersionedTransaction.deserialize(transactionBuffer);
transaction.sign([keypair]);
const signature = await connection.sendTransaction(transaction);
```
Poll `/order-status` for async orders. This returns fills and the final
status.
```typescript theme={null}
const statusResponse = await fetch(
`${API_BASE_URL}/order-status?signature=${signature}`,
{ headers }
).then((x) => x.json());
console.log(statusResponse.status, statusResponse.fills);
```
You do not call a separate endpoint to fill the order. The settlement authority
reads your limit price and side from **User Order Escrow**, submits a limit IOC
to offchain liquidity, and settles onchain. You receive outcome tokens, unused
stablecoins are refunded, platform fees are transferred, and the settlement
stablecoin moves to the **Settlement Vault**.
A limit IOC (Immediate‑Or‑Cancel) order executes immediately at the limit
price (or better) for whatever size is available right now. Any unfilled
portion is canceled instead of resting on the book.
```typescript theme={null}
const statusResponse = await fetch(
`${API_BASE_URL}/order-status?signature=${signature}`,
{ headers }
).then((x) => x.json());
if (statusResponse.status === "closed") {
console.log("Order filled", statusResponse.fills);
} else {
console.log("Order status:", statusResponse.status);
}
```
## KYC Requirements
Prediction market applications must use [Proof](/build/proof/introduction) to meet Kalshi compliance requirements.
## API Routes
* [GET /order](/build/trading-api/order/order)
* [GET /order-status](/build/trading-api/order/order-status)
## Cookbook Repository
This recipe, along with many more, is available in the
[DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can
clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Monitor Market Lifecycle
Source: https://pond.dflow.net/build/recipes/prediction-markets/monitor-market-lifecycle
How to monitor market status changes and redemption availability
During development, you can use the [developer endpoints](/build/endpoints)
without an API key. For production use, you'll need an
[API key](/build/api-key) to avoid rate limits.
Track market status to know when trading is allowed and when redemption is
available. Use the Metadata API to query status and filter by
state.
## Market Lifecycle Diagram
Use this lifecycle to decide when to trade and when to redeem. A market can move
forward through the sequence and can temporarily pause in `inactive`.
```mermaid theme={null}
flowchart LR
initialized --> active
active --> inactive
inactive --> active
inactive --> closed
active --> closed
closed --> determined
determined --> finalized
```
Monitor a fixed lifecycle:
**initialized → active → inactive → closed → determined → finalized**.
Trade only when status is **active**. Redeem only when status is
**determined** or **finalized**, and redemption is funded.
Markets can move from `inactive` back to `active`, or from `inactive` to
`closed`.
Fetch a market by mint and read the `status` and `redemptionStatus`
fields.
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const outcomeMint = "OUTCOME_TOKEN_MINT_ADDRESS";
const market = await fetch(
`${METADATA_API_BASE_URL}/api/v1/market/by-mint/${outcomeMint}`
).then((x) => x.json());
console.log({
status: market.status,
redemptionStatus: market.accounts?.[market.settlementMint]?.redemptionStatus,
});
```
Filter markets to show only tradable or redeemable markets.
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/markets?status=active&limit=200`
).then((x) => x.json());
console.log(response.markets?.length ?? 0);
```
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/markets?status=determined&limit=200`
).then((x) => x.json());
console.log(response.markets?.length ?? 0);
```
You gate trades to `active` markets and gate redemption to `determined` or
`finalized` markets with `redemptionStatus = "open"`.
```typescript theme={null}
if (market.status === "active") {
// Allow trades
} else {
// Show market status to the user
}
```
```typescript theme={null}
const settlementAccount = market.accounts?.[market.settlementMint];
if (
(market.status === "determined" || market.status === "finalized") &&
settlementAccount?.redemptionStatus === "open"
) {
// Allow redemption
}
```
## KYC Requirements
Prediction market applications must use [Proof](/build/proof/introduction) to meet Kalshi compliance requirements.
## API Routes
* [GET /api/v1/markets](/build/metadata-api/markets/markets)
* [GET /api/v1/market/by-mint/](/build/metadata-api/markets/market-by-mint)
## Cookbook Repository
This recipe, along with many more, is available in the
[DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can
clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Query Onchain Trades
Source: https://pond.dflow.net/build/recipes/prediction-markets/query-onchain-trades
How to query onchain fills by wallet, by event, and by market
During development, you can use the [developer endpoints](/build/endpoints)
without an API key. For production use, you'll need an
[API key](/build/api-key) to avoid rate limits.
Use the onchain trades endpoints to power activity feeds, trade analytics, and
wallet-level history views.
## Use Cases
* Display global "recent fills" across all markets.
* Display market-specific fills next to orderbook and price data.
* Display wallet trade history scoped to a market or event.
* Trigger alerts for large trades using `minAmount` filters.
Define the metadata API base URL and reusable query/output helpers.
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
type QueryValue = string | number | undefined | null;
type OnchainTrade = Record;
function toQueryString(params: Record): string {
const searchParams = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== "") {
searchParams.set(key, String(value));
}
});
const query = searchParams.toString();
return query ? `?${query}` : "";
}
function printTrades(trades: OnchainTrade[]) {
trades.forEach((trade) => {
console.log({
id: trade.id,
createdAt: trade.createdAt,
marketTicker: trade.marketTicker,
side: trade.side,
inputAmount: trade.inputAmount,
outputAmount: trade.outputAmount,
wallet: trade.wallet,
transactionSignature: trade.transactionSignature,
});
});
}
```
Scope fills to a single wallet using `/api/v1/onchain-trades` with the
`wallet` query parameter.
```typescript theme={null}
const wallet = "XJfdwGBgXMa1cXdiU4fqceoBLkgtTCr6S863k8xmh9A";
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/onchain-trades?wallet=${wallet}&limit=100&sortBy=createdAt&sortOrder=desc`
);
if (!response.ok) {
throw new Error("Failed to fetch wallet onchain trades");
}
const data = await response.json();
const trades = data.trades ?? [];
const nextCursor = data.cursor ?? null;
printTrades(trades);
console.log({
wallet,
tradeCount: trades.length,
nextCursor,
});
```
Scope fills across all markets using `/api/v1/onchain-trades`.
```typescript theme={null}
const query = toQueryString({
limit: 100,
cursor: undefined,
mint: undefined, // optional
ticker: undefined, // optional
sortBy: "createdAt",
sortOrder: "desc",
minAmount: undefined,
maxAmount: undefined,
});
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/onchain-trades${query}`
);
if (!response.ok) {
throw new Error("Failed to fetch onchain trades");
}
const data = await response.json();
const trades = data.trades ?? [];
const nextCursor = data.cursor ?? null;
printTrades(trades);
console.log({ tradeCount: trades.length, nextCursor });
```
Scope fills to all markets inside a single event using
`/api/v1/onchain-trades/by-event/{event_ticker}`.
```typescript theme={null}
const eventTicker = "KXBTCY-27JAN0100";
const query = toQueryString({
limit: 100,
sortBy: "createdAt",
sortOrder: "desc",
minAmount: undefined,
maxAmount: undefined,
});
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/onchain-trades/by-event/${eventTicker}${query}`
);
if (!response.ok) {
throw new Error("Failed to fetch onchain trades by event");
}
const data = await response.json();
const trades = data.trades ?? [];
const nextCursor = data.cursor ?? null;
printTrades(trades);
console.log({
eventTicker,
tradeCount: trades.length,
nextCursor,
});
```
Scope fills to a single market using
`/api/v1/onchain-trades/by-market/{market_ticker}`.
```typescript theme={null}
const marketTicker = "KXBTCY-27JAN0100-B82500";
const query = toQueryString({
limit: 100,
sortBy: "createdAt",
sortOrder: "desc",
minAmount: undefined,
maxAmount: undefined,
});
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/onchain-trades/by-market/${marketTicker}${query}`
);
if (!response.ok) {
throw new Error("Failed to fetch onchain trades by market");
}
const data = await response.json();
const trades = data.trades ?? [];
const nextCursor = data.cursor ?? null;
printTrades(trades);
console.log({
marketTicker,
tradeCount: trades.length,
nextCursor,
});
```
Scope historical pagination by passing each response `cursor` into the next
`/api/v1/onchain-trades` request.
```typescript theme={null}
async function fetchAllOnchainTrades(limitPerPage = 250) {
let cursor: string | null = null;
const allTrades: OnchainTrade[] = [];
do {
const query = toQueryString({
limit: limitPerPage,
cursor,
sortBy: "createdAt",
sortOrder: "desc",
});
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/onchain-trades${query}`
);
if (!response.ok) throw new Error("Failed to paginate onchain trades");
const page = await response.json();
allTrades.push(...(page.trades ?? []));
cursor = page.cursor ?? null;
} while (cursor);
printTrades(allTrades);
return allTrades;
}
```
## API Routes
* [GET /api/v1/onchain-trades](/build/metadata-api/trades/onchain-trades)
* [GET /api/v1/onchain-trades/by-event/](/build/metadata-api/trades/onchain-trades-by-event)
* [GET /api/v1/onchain-trades/by-market/](/build/metadata-api/trades/onchain-trades-by-market)
## Cookbook Repository
This recipe, along with many more, is available in the
[DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can
clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Redeem Outcome Tokens
Source: https://pond.dflow.net/build/recipes/prediction-markets/redeem-outcome-tokens
How to redeem determined outcome tokens
During development, you can use the [developer endpoints](/build/endpoints)
without an API key. For production use, you'll need an
[API key](/build/api-key) to avoid rate limits.
Redeem outcome tokens after a market is determined and funded for redemption by trading expired outcome tokens back into the stablecoin you opened your position with.
Use the [`/api/v1/market/by-mint/{mint_address}`](/metadata-api/markets/market-by-mint) endpoint to fetch market details and verify that the outcome token is redeemable. A token is redeemable when:
* The market status is `"determined"` or `"finalized"`
* The redemption status for the settlement mint is `"open"`
* Either:
* The market result (`"yes"` or `"no"`) matches the user's outcome token (the outcome mint must match the `yesMint` or `noMint` for the determined side), OR
* The market result is empty (`""`) and `scalarOutcomePct` is defined (rare edge case - see note below)
**Edge Case: Scalar Outcome Payouts**
In rare cases, a market may have `redemptionStatus = "open"` but `result = ""` (no result defined). In this scenario, use `scalarOutcomePct` to determine the payout:
* `scalarOutcomePct` represents the payout percentage for YES tokens in basis points (0-10000, where 10000 = 100%)
* YES token payout = `scalarOutcomePct / 10000`
* NO token payout = `(10000 - scalarOutcomePct) / 10000`
Example: If `scalarOutcomePct = 5000`, then:
* YES tokens redeem for 50% (5000/10000 = 0.5)
* NO tokens redeem for 50% ((10000-5000)/10000 = 0.5)
Both YES and NO tokens are redeemable in this case.
```typescript theme={null}
/// Base URL for the DFlow Prediction Market Metadata API
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
/// Settlement mint constant (USDC)
/// If you only support one settlement mint, use this constant
const USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
/// Outcome token mint address (YES or NO token)
const outcomeMint = "OUTCOME_TOKEN_MINT_ADDRESS_HERE";
/// Fetch market details by mint address
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/market/by-mint/${outcomeMint}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to fetch market details");
}
const market = await response.json();
/// Check if market is determined (status can be "determined" or "finalized")
if (market.status !== "determined" && market.status !== "finalized") {
throw new Error(`Market is not determined. Current status: ${market.status}`);
}
/// Check if the outcome mint matches the market result
/// The result can be "yes", "no", or "" (empty string for scalar outcomes)
const result = market.result; // "yes", "no", or ""
let isDeterminedOutcome = false;
let settlementMint;
/// Option 1: Use a constant settlement mint (e.g., USDC)
/// If you only support one settlement mint, use this approach
if (market.accounts[USDC_MINT]) {
const usdcAccount = market.accounts[USDC_MINT];
/// Check if redemption is open
if (usdcAccount.redemptionStatus === "open") {
/// Case 1: Standard determined outcome (result is "yes" or "no")
if (result === "yes" || result === "no") {
if (
(result === "yes" && usdcAccount.yesMint === outcomeMint) ||
(result === "no" && usdcAccount.noMint === outcomeMint)
) {
isDeterminedOutcome = true;
settlementMint = USDC_MINT;
}
}
/// Case 2: Scalar outcome (result is empty, use scalarOutcomePct)
/// In this rare case, both YES and NO tokens are redeemable
else if (
result === "" &&
usdcAccount.scalarOutcomePct !== null &&
usdcAccount.scalarOutcomePct !== undefined
) {
/// Both YES and NO tokens are redeemable when scalarOutcomePct is defined
if (
usdcAccount.yesMint === outcomeMint ||
usdcAccount.noMint === outcomeMint
) {
isDeterminedOutcome = true;
settlementMint = USDC_MINT;
/// Calculate payout percentages for display/logging
const yesPayoutPct = usdcAccount.scalarOutcomePct / 10000;
const noPayoutPct = (10000 - usdcAccount.scalarOutcomePct) / 10000;
console.log(
`Scalar outcome detected. YES payout: ${
yesPayoutPct * 100
}%, NO payout: ${noPayoutPct * 100}%`
);
}
}
} else {
throw new Error(`Redemption is not open for ${outcomeMint}`);
}
}
/// Option 2: Find settlement mint dynamically (if you support multiple)
/// Uncomment this if you need to support multiple settlement mints
/*
if (!settlementMint) {
for (const [mint, account] of Object.entries(market.accounts)) {
if (account.redemptionStatus === "open") {
/// Case 1: Standard determined outcome
if (result === "yes" || result === "no") {
if (result === "yes" && account.yesMint === outcomeMint) {
isDeterminedOutcome = true;
settlementMint = mint;
break;
} else if (result === "no" && account.noMint === outcomeMint) {
isDeterminedOutcome = true;
settlementMint = mint;
break;
}
}
/// Case 2: Scalar outcome (both YES and NO are redeemable)
else if (result === "" && account.scalarOutcomePct !== null && account.scalarOutcomePct !== undefined) {
if (account.yesMint === outcomeMint || account.noMint === outcomeMint) {
isDeterminedOutcome = true;
settlementMint = mint;
break;
}
}
} else {
throw new Error(`Redemption is not open for ${outcomeMint}`);
}
}
}
*/
if (!isDeterminedOutcome) {
if (result === "") {
throw new Error(
`Outcome token does not match any outcome mint for this market. Token: ${outcomeMint}`
);
} else {
throw new Error(
`Outcome token does not match market result. Market result: ${result}, Token: ${outcomeMint}`
);
}
}
if (!settlementMint) {
throw new Error("No settlement mint with open redemption status found");
}
const settlementAccount = market.accounts[settlementMint];
console.log("Token is redeemable!", {
outcomeMint,
settlementMint,
redemptionStatus: settlementAccount.redemptionStatus,
marketTitle: market.title,
});
```
Use the Trade API [`/order`](/trading-api/order/order) endpoint to request a redemption order. The redemption is treated as a trade where you swap your outcome token for the settlement stablecoin.
```typescript theme={null}
/// Base URL for the DFlow Trade API
const API_BASE_URL = "https://dev-quote-api.dflow.net";
/// Settlement mint constant (USDC)
const USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
/// Outcome token mint (YES or NO token you hold)
const outcomeMint = "OUTCOME_TOKEN_MINT_ADDRESS_HERE";
/// Settlement mint (use the constant or the value found in Step 1)
const settlementMint = USDC_MINT;
/// Amount of outcome tokens to redeem. Outcome tokens always have 6 decimals.
const amount = 1000000; // Example: 1 outcome token (6 decimals)
/// User's public key
const userPublicKey = keypair.publicKey.toBase58();
const queryParams = new URLSearchParams();
queryParams.append("userPublicKey", userPublicKey);
queryParams.append("inputMint", outcomeMint);
queryParams.append("outputMint", settlementMint);
queryParams.append("amount", amount.toString());
const orderResponse = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`
).then((x) => x.json());
console.log(
`Redemption order received! ${orderResponse.inAmount} of ${orderResponse.inputMint} is redeemable for ${orderResponse.outAmount} of ${orderResponse.outputMint}`
);
```
Wait for the settlement authority to write the outcome into the
**Market Ledger**. You cannot redeem until the outcome is determined.
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const outcomeMint = "OUTCOME_TOKEN_MINT_ADDRESS";
const market = await fetch(
`${METADATA_API_BASE_URL}/api/v1/market/by-mint/${outcomeMint}`
).then((x) => x.json());
if (market.status === "determined" || market.status === "finalized") {
console.log("Outcome determined");
} else {
console.log("Outcome not determined yet");
}
```
Wait for the settlement authority to fund redemption by moving
stablecoins from the **Settlement Vault** to the **Redemption Vault**.
```typescript theme={null}
const settlementAccount = market.accounts?.[market.settlementMint];
if (settlementAccount?.redemptionStatus === "open") {
console.log("Redemption funded");
} else {
console.log("Redemption not funded yet");
}
```
Redeem your expired outcome tokens into the settlement
stablecoin using the Trade API.
```typescript theme={null}
const API_BASE_URL = "https://dev-quote-api.dflow.net";
const API_KEY = process.env.DFLOW_API_KEY; // Optional
const outcomeMint = "OUTCOME_TOKEN_MINT_ADDRESS";
const settlementMint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; // USDC
const amount = 1_000_000; // 1 outcome token (6 decimals)
const queryParams = new URLSearchParams();
queryParams.append("inputMint", outcomeMint);
queryParams.append("outputMint", settlementMint);
queryParams.append("amount", amount.toString());
queryParams.append("userPublicKey", keypair.publicKey.toBase58());
const headers: HeadersInit = {};
if (API_KEY) {
headers["x-api-key"] = API_KEY;
}
const orderResponse = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`,
{ headers }
).then((x) => x.json());
```
Submit the redemption order transaction so the Trade API can execute the
payout onchain.
```typescript theme={null}
const transactionBuffer = Buffer.from(orderResponse.transaction, "base64");
const transaction = VersionedTransaction.deserialize(transactionBuffer);
transaction.sign([keypair]);
const signature = await connection.sendTransaction(transaction);
```
Track the order until it closes so you can confirm the redemption was
finalized.
```typescript theme={null}
const statusResponse = await fetch(
`${API_BASE_URL}/order-status?signature=${signature}`,
{ headers }
).then((x) => x.json());
console.log(statusResponse.status, statusResponse.fills);
```
## KYC Requirements
Prediction market applications must use [Proof](/build/proof/introduction) to meet Kalshi compliance requirements.
## API Routes
* [GET /api/v1/market/by-mint/](/build/metadata-api/markets/market-by-mint)
* [GET /order](/build/trading-api/order/order)
* [GET /order-status](/build/trading-api/order/order-status)
## Cookbook Repository
This recipe, along with many more, is available in the
[DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can
clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Track User Positions
Source: https://pond.dflow.net/build/recipes/prediction-markets/track-positions
How to track user prediction market positions
During development, you can use the [developer endpoints](/build/endpoints)
without an API key. For production use, you'll need an
[API key](/build/api-key) to avoid rate limits.
Track positions by reading wallet token balances, filtering for outcome mints,
and mapping those mints to markets and outcomes. Use this flow for portfolio
views, position tables, and redemption eligibility checks.
Fetch SPL token accounts for the wallet and keep only non-zero balances.
Outcome tokens are Token-2022 mints, so query the Token-2022 program.
```typescript theme={null}
import { Connection, PublicKey } from "@solana/web3.js";
import { TOKEN_2022_PROGRAM_ID } from "@solana/spl-token";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const userWallet = new PublicKey("USER_WALLET_ADDRESS_HERE");
const tokenAccounts = await connection.getParsedTokenAccountsByOwner(
userWallet,
{ programId: TOKEN_2022_PROGRAM_ID }
);
const userTokens = tokenAccounts.value.map(({ account }) => {
const info = account.data.parsed.info;
return {
mint: info.mint,
rawBalance: info.tokenAmount.amount,
balance: info.tokenAmount.uiAmount,
decimals: info.tokenAmount.decimals,
};
});
const nonZeroBalances = userTokens.filter((token) => token.balance > 0);
```
Filter the wallet mints down to prediction market outcome tokens using the
Metadata API.
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const allMintAddresses = nonZeroBalances.map((token) => token.mint);
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/filter_outcome_mints`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ addresses: allMintAddresses }),
}
);
if (!response.ok) {
throw new Error("Failed to filter outcome mints");
}
const data = await response.json();
const outcomeMints = data.outcomeMints ?? [];
const outcomeTokens = nonZeroBalances.filter((token) =>
outcomeMints.includes(token.mint)
);
```
Pull market metadata for those outcome mints so you can label YES/NO and
display event and market context.
```typescript theme={null}
const marketsResponse = await fetch(
`${METADATA_API_BASE_URL}/api/v1/markets/batch`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ mints: outcomeMints }),
}
);
if (!marketsResponse.ok) {
throw new Error("Failed to fetch markets batch");
}
const marketsData = await marketsResponse.json();
const markets = marketsData.markets ?? [];
const marketsByMint = new Map();
markets.forEach((market: any) => {
Object.values(market.accounts ?? {}).forEach((account: any) => {
if (account.yesMint) marketsByMint.set(account.yesMint, market);
if (account.noMint) marketsByMint.set(account.noMint, market);
});
});
```
Map each outcome token to a market, determine YES/NO, and shape the data
for your UI.
```typescript theme={null}
const positions = outcomeTokens.map((token) => {
const market = marketsByMint.get(token.mint);
if (!market) {
return {
mint: token.mint,
balance: token.balance,
position: "UNKNOWN",
market: null,
};
}
const accounts = Object.values(market.accounts ?? {});
const isYesToken = accounts.some((account: any) => account.yesMint === token.mint);
const isNoToken = accounts.some((account: any) => account.noMint === token.mint);
return {
mint: token.mint,
balance: token.balance,
decimals: token.decimals,
position: isYesToken ? "YES" : isNoToken ? "NO" : "UNKNOWN",
market,
};
});
```
## KYC Requirements
Prediction market applications must use [Proof](/build/proof/introduction) to meet Kalshi compliance requirements.
## API Routes
* [POST /api/v1/filter\_outcome\_mints](/build/metadata-api/markets/filter-outcome-mints)
* [POST /api/v1/markets/batch](/build/metadata-api/markets/markets-batch)
## Cookbook Repository
This recipe, along with many more, is available in the
[DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can
clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# From Spot Tokens to Prediction Market Positions
Source: https://pond.dflow.net/build/recipes/prediction-markets/trade-into-position
Understanding how trades route from spot tokens to outcome tokens
During development, you can use the [developer endpoints](/build/endpoints)
without an API key. For production use, you'll need an
[API key](/build/api-key) to avoid rate limits.
When trading into a prediction market, DFlow lets you trade from any arbitrary input mint directly into a prediction market outcome token.
For example, a user can trade from `BONK -> outcome token`, without first swapping `BONK → CASH` and then `CASH -> outcome token`. This removes extra steps and streamlines application logic.
Using the settlement mint (USDC or CASH) as the input is the fastest path. If you input a different token (e.g., SOL), the system adds a swap leg to convert to the settlement mint first, which adds roughly **50ms** of latency. For the lowest latency trades, use the settlement mint directly.
## Trading Flow Overview
When you want to trade a spot token for a prediction market outcome token, the `/order` endpoint orchestrates the entire transaction flow behind the scenes. The endpoint automatically:
1. Detects whether the target market has been tokenized (initialized)
2. Executes a two-step swap path: Input Token → Settlement Mint → Outcome Token
3. Handles market tokenization if the market hasn't been initialized yet
The `/order` endpoint accepts any spot token as `inputMint` and any outcome
token mint as `outputMint`. The endpoint automatically constructs the
appropriate transaction path based on the market's initialization status.
If you start from a wallet's token balances, filter down to outcome mints
before selecting your target `outputMint`.
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const allMintAddresses = nonZeroBalances.map((token) => token.mint);
const response = await fetch(
`${METADATA_API_BASE_URL}/api/v1/filter_outcome_mints`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ addresses: allMintAddresses }),
}
);
if (!response.ok) {
throw new Error("Failed to filter outcome mints");
}
const data = await response.json();
const outcomeMints = data.outcomeMints ?? [];
const outcomeTokens = nonZeroBalances.filter((token) =>
outcomeMints.includes(token.mint)
);
```
## Transaction Flow
All trades from spot tokens to outcome tokens follow a two-step swap path that route through the settlement mint as an intermediate step:
1. **Input Token → Settlement Mint**
2. **Settlement Mint → Outcome Token**
The `/order` endpoint returns a single transaction that executes both swaps.
```typescript theme={null}
import { Connection, PublicKey, VersionedTransaction } from "@solana/web3.js";
const API_BASE_URL = "https://dev-quote-api.dflow.net";
const API_KEY = process.env.DFLOW_API_KEY; // Optional for dev
const connection = new Connection("https://api.mainnet-beta.solana.com");
const userPublicKey = new PublicKey("USER_WALLET_ADDRESS_HERE");
const inputMint = "So11111111111111111111111111111111111111112"; // SOL
const outputMint = "OUTCOME_TOKEN_MINT_ADDRESS";
const amount = 1_000_000_000; // 1 SOL (9 decimals)
const queryParams = new URLSearchParams({
inputMint,
outputMint,
amount: amount.toString(),
userPublicKey: userPublicKey.toBase58(),
});
const headers: HeadersInit = {};
if (API_KEY) {
headers["x-api-key"] = API_KEY;
}
const orderResponse = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`,
{ headers }
).then((x) => x.json());
const transactionBuffer = Buffer.from(orderResponse.transaction, "base64");
const transaction = VersionedTransaction.deserialize(transactionBuffer);
// sign with the user's keypair in your app
transaction.sign([userKeypair]);
const signature = await connection.sendTransaction(transaction);
```
```typescript theme={null}
const statusResponse = await fetch(
`${API_BASE_URL}/order-status?signature=${signature}`,
{ headers }
).then((x) => x.json());
console.log(statusResponse.status, statusResponse.fills);
```
## Market Initialization States
The `/order` endpoint automatically detects whether the target market has been tokenized and handles the transaction accordingly:
### Initialized Markets
When a market has already been tokenized, the transaction executes the two-step swap path directly:
**Input Token → Settlement Mint → Outcome Token**
### Uninitialized Markets
When a market hasn't been tokenized yet, the `/order` endpoint automatically includes market tokenization in the transaction before executing the swap:
**Market Tokenization + (Input Token → Settlement Mint → Outcome Token)**
The transaction will:
1. First perform on-demand market tokenization (creating the YES and NO outcome tokens on-chain)
2. Then execute the two-step swap: Input Token → Settlement Mint → Outcome Token
On-demand market creation (tokenization) incurs a small fee. This fee is
automatically included in the transaction when trading into an uninitialized
market.
### Checking Market Status
You can check a market's initialization status using the [Prediction Market Metadata API](/metadata-api/markets/markets). The `isInitialized` field in the market response indicates whether the market has been tokenized:
* `isInitialized: true` - Market is already tokenized; direct swap path.
* `isInitialized: false` - Market needs tokenization; transaction will include initialization.
While you can check this status for informational purposes, the `/order` endpoint handles the detection automatically, so you don't need to check beforehand.
```typescript theme={null}
const METADATA_API_BASE_URL = "https://dev-prediction-markets-api.dflow.net";
const marketMint = "OUTCOME_TOKEN_MINT_ADDRESS";
const marketResponse = await fetch(
`${METADATA_API_BASE_URL}/api/v1/market/by-mint/${marketMint}`
).then((x) => x.json());
console.log(marketResponse.isInitialized);
```
## KYC Requirements
Prediction market applications must use [Proof](/build/proof/introduction) to meet Kalshi compliance requirements.
## API Routes
* [POST /api/v1/filter\_outcome\_mints](/build/metadata-api/markets/filter-outcome-mints)
* [GET /api/v1/market/by-mint/](/build/metadata-api/markets/market-by-mint)
* [GET /order](/build/trading-api/order/order)
* [GET /order-status](/build/trading-api/order/order-status)
## Key Takeaways
* The `/order` endpoint accepts any spot token as input and any outcome token as output.
* All trades execute through the settlement mint as an intermediate step: Input Token → Settlement Mint → Outcome Token.
* For initialized markets, the transaction executes the swap path directly.
* For uninitialized markets, the transaction includes market tokenization before executing the swap path.
* On-demand market creation (tokenization) incurs a small fee.
* The endpoint automatically detects market initialization status and constructs the appropriate transaction.
* You can check `isInitialized` via the metadata API.
## Related Resources
Complete API reference for the `/order` endpoint, including all parameters
and response formats
Learn how to use the DFlow Trade API to execute trades programmatically
Query market data including initialization status and outcome token
addresses
Learn how to find markets and access outcome token mint addresses for
trading
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Declarative Trade
Source: https://pond.dflow.net/build/recipes/trading/declarative-trade
How to execute declarative trades with the DFlow Trading API
During development, you can use the [developer endpoints](/build/endpoints) without an API key. For production use, you'll need an [API key](/build/api-key) to avoid rate limits.
Use [Declarative Trades](/learn/declarative-trades) to trade tokens with less slippage, lower latency, and better pricing.
To execute a declarative trade, request an intent from `/intent`, sign the open
transaction, submit the intent, then monitor until it settles.
```mermaid theme={null}
flowchart LR
A[Request /intent] --> B[Sign open transaction]
B --> C[Submit intent]
C --> D[Monitor status]
```
Request an intent quote from the DFlow Trading API. The `/intent` response returns
an **open order transaction** that signals the trader’s intent to swap at a
guaranteed minimum quote with a slippage tolerance. This intent defines the
constraints (pair, amount, slippage, fees), not a fixed route.
```typescript theme={null}
const SOL = "So11111111111111111111111111111111111111112";
const USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
/// Amount of SOL to trade to USDC
const amount = 1_000_000_000;
/// Slippage tolerance in bps
const slippageBps = 1;
/// Base URL for the DFlow Trading API
const AGGREGATOR_API_BASE_URL = "https://dev-quote-api.dflow.net";
const API_KEY = process.env.DFLOW_API_KEY; // Optional
const queryParams = new URLSearchParams();
queryParams.append("inputMint", SOL);
queryParams.append("outputMint", USDC);
queryParams.append("amount", amount.toString());
queryParams.append("userPublicKey", keypair.publicKey.toBase58());
queryParams.append("slippageBps", slippageBps.toString());
const headers: HeadersInit = {};
if (API_KEY) {
headers["x-api-key"] = API_KEY;
}
const intentResponse = await fetch(
`${AGGREGATOR_API_BASE_URL}/intent?${queryParams.toString()}`,
{ headers }
);
const intentData = await intentResponse.json();
```
Sign the intent, guaranteeing the minimum amount of output tokens without committing to any given route plan.
```typescript theme={null}
const transaction = intentData.openTransaction;
const transactionBytes = Buffer.from(transaction, "base64");
const openTransaction = Transaction.from(transactionBytes);
openTransaction.sign(keypair);
```
Intents are submitted to the DFlow Aggregator, which optimizes the execution of the trade based on network conditions.
```typescript theme={null}
const headers: HeadersInit = {
"Content-Type": "application/json",
};
if (API_KEY) {
headers["x-api-key"] = API_KEY;
}
const response = await fetch(`${AGGREGATOR_API_BASE_URL}/submit-intent`, {
method: "POST",
headers,
body: JSON.stringify({
quoteResponse: intentData,
signedOpenTransaction: Buffer.from(openTransaction.serialize()).toString(
"base64"
),
}),
});
const submitIntentData = await response.json();
```
After submitting the Intent, monitor its status using the `monitorOrder` helper function from the
[`@dflow-protocol/swap-api-utils`](https://www.npmjs.com/package/@dflow-protocol/swap-api-utils) package.
```typescript theme={null}
const result = await monitorOrder({
connection,
intent: intentData,
signedOpenTransaction: openTransaction,
submitIntentResponse: submitIntentData,
});
switch (result.status) {
case ORDER_STATUS.CLOSED: {
if (result.fills.length > 0) {
// Order was filled and closed
const qtyIn = result.fills.reduce((acc, x) => acc + x.qtyIn, 0n);
const qtyOut = result.fills.reduce((acc, x) => acc + x.qtyOut, 0n);
console.log(`Order succeeded: sent ${qtyIn}, received ${qtyOut}`);
} else {
// Order was closed without any fills
console.log("Order failed");
}
break;
}
case ORDER_STATUS.PENDING_CLOSE: {
if (result.fills.length > 0) {
// Order was filled and is now closable
const qtyIn = result.fills.reduce((acc, x) => acc + x.qtyIn, 0n);
const qtyOut = result.fills.reduce((acc, x) => acc + x.qtyOut, 0n);
console.log(`Order succeeded: sent ${qtyIn}, received ${qtyOut}`);
} else {
// Order was not filled and is now closable
console.log("Order failed");
}
break;
}
case ORDER_STATUS.OPEN_EXPIRED: {
// Transaction to open the order expired
console.log(
"Transaction expired. Try again with a higher slippage tolerance."
);
break;
}
case ORDER_STATUS.OPEN_FAILED: {
// Transaction to open the order was executed and failed
console.log("Order failed", result.transactionError);
break;
}
}
```
## API Routes
* [GET /intent](/build/trading-api/declarative/quote)
* [POST /submit-intent](/build/trading-api/declarative/submit)
## Cookbook Repository
This recipe, along with many more, is available in the [DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Imperative Trade
Source: https://pond.dflow.net/build/recipes/trading/imperative-trade
How to execute imperative trades with the DFlow Trading API
During development, you can use the [developer endpoints](/build/endpoints) without an API key. For production use, you'll need an [API key](/build/api-key) to avoid rate limits.
With [imperative trades](/learn/imperative-trades), **builders define the exact execution path** for a trade, including which venues are used and how the transaction is constructed. Use imperative trades when you need deterministic routing, [venue control](/learn/liquidity-venues), or strategy-driven execution.
The API aggregates liquidity across major Solana DEXs, so builders can execute trades on any SPL token while retaining full control over how execution happens.
To execute an imperative trade, request an order from `/order` (with
`userPublicKey`), sign it, and submit it to your RPC.
```mermaid theme={null}
flowchart LR
A[Request /order] --> B[Sign transaction]
B --> C[Submit to RPC]
C --> D[Confirm status]
```
Request an order from `/order` using `userPublicKey`, input/output mints,
amount, slippage, and your execution path. The response returns a
base64-encoded transaction.
Use `dexes` to enforce a deterministic path (for example, a single venue).
```typescript theme={null}
const connection = new Connection(SOLANA_RPC_URL, "confirmed");
const keypair = getKeypair();
const inputMint = "So11111111111111111111111111111111111111112"; // SOL
const outputMint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; // USDC
const inputAmount = 100000; // 0.0001 SOL (9 decimals)
const slippageBps = 50; // 0.5%
const dexes = ["Raydium AMM"]; // single venue for deterministic path
const order = await fetchOrder({
userPublicKey: keypair.publicKey.toBase58(),
inputMint,
outputMint,
amount: inputAmount,
slippageBps,
dexes,
});
```
Deserialize the base64 transaction and sign it with the user's keypair.
```typescript theme={null}
const transactionBuffer = Buffer.from(order.transaction, "base64");
const tx = VersionedTransaction.deserialize(transactionBuffer);
tx.sign([keypair]);
```
Submit the signed transaction to a Solana RPC and wait for confirmation.
```typescript theme={null}
const signature = await connection.sendRawTransaction(tx.serialize(), {
skipPreflight: false,
});
console.log(`Transaction sent: ${signature}`);
await connection.confirmTransaction(signature, "confirmed");
console.log("Transaction confirmed");
await sendTransaction(connection, tx);
```
## API Routes
* [GET /order](/build/trading-api/order/order)
## Cookbook Repository
This recipe, along with many more, is available in the [DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Implement Platform Fees
Source: https://pond.dflow.net/build/recipes/trading/platform-fees
How to implement platform fees with the DFlow Trading API
During development, you can use the [developer endpoints](/build/endpoints) without an API key. For production use, you'll need an [API key](/build/api-key) to avoid rate limits.
Use [`platformFeeBps`](/trading-api/order/order#parameter-platform-fee-bps) to specify a fixed fee in basis points. Control which token the fee is collected from using [`platformFeeMode`](/trading-api/order/order#parameter-platform-fee-mode).
```typescript theme={null}
const SOL = "So11111111111111111111111111111111111111112";
const USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
const API_BASE_URL = "https://dev-quote-api.dflow.net";
const queryParams = new URLSearchParams();
queryParams.append("inputMint", SOL);
queryParams.append("outputMint", USDC);
queryParams.append("amount", "1000000000");
queryParams.append("platformFeeBps", "50"); // 0.5% fee
queryParams.append("platformFeeMode", "outputMint"); // Collect from output (USDC)
queryParams.append("feeAccount", "YourUSDCTokenAccountAddress");
queryParams.append("userPublicKey", keypair.publicKey.toBase58());
const orderResponse = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`
).then((x) => x.json());
```
```typescript theme={null}
/// To collect fee from input mint instead
queryParams.append("platformFeeMode", "inputMint");
queryParams.append("feeAccount", "YourSOLTokenAccountAddress"); // Must match input mint
```
```typescript theme={null}
/// For /quote endpoint (imperative swaps)
const quoteResponse = await fetch(
`${API_BASE_URL}/quote?${queryParams.toString()}`
).then((x) => x.json());
/// For /intent endpoint (declarative swaps)
const intentResponse = await fetch(
`${API_BASE_URL}/intent?${queryParams.toString()}`
).then((x) => x.json());
```
For [outcome token](/concepts/prediction/prediction-market-terminology#outcome-token) trades, use [`platformFeeScale`](/trading-api/order/order#parameter-platform-fee-scale) instead of `platformFeeBps`. The fee is calculated dynamically based on market probability.
```typescript theme={null}
const SOL = "So11111111111111111111111111111111111111112";
const OUTCOME_TOKEN_MINT = "YourOutcomeTokenMint";
const API_BASE_URL = "https://dev-quote-api.dflow.net";
const queryParams = new URLSearchParams();
queryParams.append("inputMint", SOL);
queryParams.append("outputMint", OUTCOME_TOKEN_MINT);
queryParams.append("amount", "1000000000");
queryParams.append("platformFeeScale", "50"); // k = 0.050 in formula k * p * (1 - p) * c
queryParams.append("feeAccount", "YourSettlementMintTokenAccountAddress");
queryParams.append("userPublicKey", keypair.publicKey.toBase58());
const orderResponse = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`
).then((x) => x.json());
```
For outcome token trades, `platformFeeMode` is ignored and the fee is always
collected in the [settlement
mint](/concepts/prediction/prediction-market-terminology#settlement-mint). See
the [Platform Fees Overview](/concepts/platform-fees-overview) for details on
the dynamic fee formula.
The [`feeAccount`](/trading-api/order/order#parameter-fee-account) parameter is required and must match the fee mint. The account must exist before the trade executes.
The fee account must match the token you're collecting fees in. For outcome
token trades, use a settlement mint token account. For other trades, match the
input or output mint based on `platformFeeMode`.
Both `/order` and `/quote` responses include `platformFee` information.
```typescript theme={null}
const orderResponse = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`
).then((x) => x.json());
if (orderResponse.platformFee) {
console.log("Platform fee details:", {
amount: orderResponse.platformFee.amount,
feeBps: orderResponse.platformFee.feeBps,
feeAccount: orderResponse.platformFee.feeAccount,
});
}
```
## Related Resources
Learn about the theory behind platform fees and the differences between
fixed and dynamic fees.
Complete API reference for the `/order` endpoint.
API reference for the `/quote` endpoint.
API reference for the `/intent` endpoint.
## API Routes
* [GET /order](/build/trading-api/order/order)
* [GET /quote](/build/trading-api/imperative/quote)
* [GET /intent](/build/trading-api/declarative/quote)
## Cookbook Repository
This recipe, along with many more, is available in the [DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Use Priority Fees
Source: https://pond.dflow.net/build/recipes/trading/priority-fees
How to set priority fees for Trading API requests
During development, you can use the [developer endpoints](/build/endpoints) without
an API key. For production use, you'll need an [API key](/build/api-key) to avoid
rate limits.
Priority fees only affect **when** a trade executes. They do not change routing,
slippage checks, or trade semantics ([what priority fees do not affect](/build/trading/priority-fees#what-priority-fees-do-not-affect)).
[How DFlow handles priority fees](/build/trading/priority-fees#how-dflow-handles-priority-fees) details the two modes.
Use [max priority fee](/build/trading/priority-fees#max-priority-fee) for adaptive speed
(server selects a fee up to your cap), or [exact priority fee](/build/trading/priority-fees#exact-priority-fee)
when you need predictable costs.
Set `prioritizationFeeLamports` on the `/order` request as either a lamport
value or one of `auto`, `medium`, `high`, `veryHigh`, `disabled`.
```typescript theme={null}
const queryParams = new URLSearchParams();
queryParams.append("inputMint", SOL);
queryParams.append("outputMint", USDC);
queryParams.append("amount", amount.toString());
queryParams.append("userPublicKey", keypair.publicKey.toBase58());
queryParams.append("slippageBps", "50");
// Adaptive fee chosen by the server.
queryParams.append("prioritizationFeeLamports", "high");
// Or use automatic selection:
// queryParams.append("prioritizationFeeLamports", "auto");
const orderResponse = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`
).then((x) => x.json());
```
```typescript theme={null}
const queryParams = new URLSearchParams();
queryParams.append("inputMint", SOL);
queryParams.append("outputMint", USDC);
queryParams.append("amount", amount.toString());
queryParams.append("userPublicKey", keypair.publicKey.toBase58());
queryParams.append("slippageBps", "50");
// Fixed priority fee in lamports.
queryParams.append("prioritizationFeeLamports", "20000");
const orderResponse = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`
).then((x) => x.json());
```
For intents, set `feeBudget` on the `/intent` request to your desired
priority fee plus the 10,000 lamport base processing fee.
```typescript theme={null}
const desiredPriorityFeeLamports = 20_000;
const baseProcessingFeeLamports = 10_000;
const feeBudget = desiredPriorityFeeLamports + baseProcessingFeeLamports;
const queryParams = new URLSearchParams();
queryParams.append("inputMint", SOL);
queryParams.append("outputMint", USDC);
queryParams.append("amount", amount.toString());
queryParams.append("userPublicKey", keypair.publicKey.toBase58());
queryParams.append("slippageBps", "50");
queryParams.append("feeBudget", feeBudget.toString());
const intentResponse = await fetch(
`${API_BASE_URL}/intent?${queryParams.toString()}`
).then((x) => x.json());
```
## API Routes
* [GET /order](/build/trading-api/order/order)
* [GET /intent](/build/trading-api/declarative/quote)
* [POST /submit-intent](/build/trading-api/declarative/submit)
## Cookbook Repository
This recipe, along with many more, is available in the
[DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can
clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Trading Tokens
Source: https://pond.dflow.net/build/recipes/trading/trade-tokens
How to outcome trade tokens with the DFlow Trade API
During development, you can use the [developer endpoints](/build/endpoints) without an API key. For production use, you'll need an [API key](/build/api-key) to avoid rate limits.
When working with prediction markets, you use the Metadata API to discover markets, and the Trade API to trade them. This receipe demonstrates how to trade a prediction market outcome token.
This recipe assumes familiarity with Solana's transaction and network
connection logic. If unfamiliar, please refer to the [Solana
Cookbook](https://solana.com/developers/cookbook).
The Trade API's GET [`/order`](/trading-api/order/order) endpoint returns a quote and open transaction in a single request.
```typescript theme={null}
const SOL = "So11111111111111111111111111111111111111112";
const USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
/// Amount of SOL to trade to USDC
const amount = 1_000_000_000;
/// Slippage tolerance in bps
const slippageBps = 50;
/// Base URL for the DFlow Trade API
const API_BASE_URL = "https://dev-quote-api.dflow.net";
const API_KEY = process.env.DFLOW_API_KEY; // Optional
const queryParams = new URLSearchParams();
queryParams.append("inputMint", SOL);
queryParams.append("outputMint", USDC);
queryParams.append("amount", amount.toString());
queryParams.append("slippageBps", slippageBps.toString());
queryParams.append("userPublicKey", keypair.publicKey.toBase58());
const headers: HeadersInit = {};
if (API_KEY) {
headers["x-api-key"] = API_KEY;
}
const orderResponse = await fetch(
`${API_BASE_URL}/order?${queryParams.toString()}`,
{ headers }
).then((x) => x.json());
```
Deserialize the transaction, sign it with your keypair, and submit it to Solana using your RPC connection.
```typescript theme={null}
/// Deserialize the transaction from base64
const transactionBuffer = Buffer.from(orderResponse.transaction, "base64");
const transaction = VersionedTransaction.deserialize(transactionBuffer);
/// Sign the transaction
transaction.sign([keypair]);
/// Send the transaction to Solana
const signature = await connection.sendTransaction(transaction);
```
How you monitor order completion depends on the `executionMode` returned from the order request:
**Sync trades** execute atomically in a single transaction. Use standard RPC confirmation.
**Async trades** execute across multiple transactions. Use the [`/order-status`](/trading-api/order/order-status) endpoint to poll for completion.
For synchronous trades that execute atomically, use standard Solana transaction confirmation:
```typescript theme={null}
if (orderData.executionMode === "sync") {
/// Monitor transaction status using getSignatureStatuses
let status;
do {
const statusResult = await connection.getSignatureStatuses([signature]);
status = statusResult.value[0];
if (!status) {
console.log("Waiting for transaction confirmation...");
await new Promise((resolve) => setTimeout(resolve, 1000));
}
} while (
!status ||
status.confirmationStatus === "processed" ||
status.confirmationStatus === "confirmed"
);
/// Check if transaction succeeded or failed
if (status.err) {
console.error("Transaction failed:", status.err);
} else {
console.log(`Trade completed successfully in slot ${status.slot}`);
}
}
```
For asynchronous trades that execute across multiple transactions, poll the `/order-status` endpoint:
```typescript theme={null}
if (orderData.executionMode === "async") {
let status;
let fills = [];
do {
/// Poll the order status endpoint
const headers: HeadersInit = {};
if (API_KEY) {
headers["x-api-key"] = API_KEY;
}
const statusResponse = await fetch(
`${API_BASE_URL}/order-status?signature=${signature}`,
{ headers }
);
const statusData = await statusResponse.json();
status = statusData.status;
fills = statusData.fills || [];
console.log(`Order status: ${status}`);
/// Wait before polling again if order is still open
if (status === "open" || status === "pendingClose") {
await new Promise((resolve) => setTimeout(resolve, 2000));
}
} while (status === "open" || status === "pendingClose");
/// Process final status
switch (status) {
case "closed": {
if (fills.length > 0) {
console.log(`Trade completed`);
} else {
console.log("Order was closed without any fills");
}
break;
}
case "pendingClose": {
if (fills.length > 0) {
console.log(`Trade ready to close`);
} else {
console.log("Order is ready to close without any fills");
}
break;
}
case "failed": {
console.log("Order failed to execute");
break;
}
}
}
```
## API Routes
* [GET /order](/build/trading-api/order/order)
* [GET /order-status](/build/trading-api/order/order-status)
## Cookbook Repository
This recipe, along with many more, is available in the [DFlow Cookbook Repo](https://github.com/DFlowProtocol/cookbook). You can clone it and start coding immediately.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Introduction
Source: https://pond.dflow.net/build/recipes/wallets/introduction
How to add wallets to your app
Use these guides to add wallet access and embedded wallets to your app.
Add Phantom Connect to a Next.js + React app.
Add Privy to a Next.js + React app.
Add Turnkey Embedded Wallet Kit to a Next.js + React app.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Phantom Connect
Source: https://pond.dflow.net/build/recipes/wallets/phantom-connect
How to add Phantom Connect to a Next.js + React app
Use Phantom Connect to add wallet access, embedded wallets, and social login to a
Next.js + React app.
This recipe covers adding Phantom Connect to a Next.js + React app. Use their [Browser SDK](https://docs.phantom.com/sdks/browser-sdk/index) for
non-React web apps and the [React Native SDK](https://docs.phantom.com/sdks/react-native-sdk/index)
for mobile apps.
## Prerequisites
Create a [Phantom Portal](https://phantom.com/portal/) app, configure allowed
domains and redirect URLs, and copy the App ID.
## Step-by-step (Next.js + React)
Use the [React SDK](https://docs.phantom.com/sdks/react-sdk) for Next.js + React.
```bash theme={null}
npm install @phantom/react-sdk @solana/web3.js
```
```bash theme={null}
npx -y create-solana-dapp@latest -t solana-foundation/templates/community/phantom-embedded-react
```
Wrap your root layout so Phantom Connect can manage auth and wallet state.
Put your App ID in `config.appId` (see `appId: "your-app-id"` in the examples)
and set the redirect URL you configured.
Create a client-side provider component, then wrap it in `app/layout.tsx`.
```tsx theme={null}
// app/providers.tsx
"use client";
import { PhantomProvider, darkTheme } from "@phantom/react-sdk";
import { AddressType } from "@phantom/browser-sdk";
export function Providers({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```
```tsx theme={null}
// app/layout.tsx
import { Providers } from "./providers";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
{children}
);
}
```
Wrap your app in `pages/_app.tsx`.
```tsx theme={null}
// pages/_app.tsx
import type { AppProps } from "next/app";
import { PhantomProvider, darkTheme } from "@phantom/react-sdk";
import { AddressType } from "@phantom/browser-sdk";
export default function App({ Component, pageProps }: AppProps) {
return (
);
}
```
Use the built-in modal or ConnectButton to trigger the Phantom flow.
```tsx theme={null}
"use client";
import { useModal, usePhantom } from "@phantom/react-sdk";
function WalletComponent() {
const { open } = useModal();
const { isConnected } = usePhantom();
if (isConnected) return
Connected
;
return ;
}
```
```tsx theme={null}
"use client";
import { ConnectButton } from "@phantom/react-sdk";
function Header() {
return ;
}
```
Use [theming](https://docs.phantom.com/sdks/react-sdk#theming) to customize
the modal UI.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Privy
Source: https://pond.dflow.net/build/recipes/wallets/privy
How to add Privy to a Next.js + React app
Use Privy to add authentication and embedded wallets to a Next.js + React app.
Privy supports multiple authentication methods (email, socials, passkeys, and
external wallets). This guide uses email OTP as a simple starting point.
## Prerequisites
Create a Privy app in the [Privy Dashboard](https://dashboard.privy.io/) and
copy your App ID.
## Step-by-step (Next.js + React)
Install the [React SDK](https://docs.privy.io/basics/react/quickstart).
```bash theme={null}
npm install @privy-io/react-auth
```
Put your App ID in `appId="your-app-id"` and wrap your app root. For Solana
embedded wallets, set `embeddedWallets.solana.createOnLogin` to create
wallets on login.
Create a client-side provider component, then wrap it in `app/layout.tsx`.
```tsx theme={null}
// app/providers.tsx
"use client";
import { PrivyProvider } from "@privy-io/react-auth";
export function Providers({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```
```tsx theme={null}
// app/layout.tsx
import { Providers } from "./providers";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
{children}
);
}
```
Wrap your app in `pages/_app.tsx`.
```tsx theme={null}
// pages/_app.tsx
import type { AppProps } from "next/app";
import { PrivyProvider } from "@privy-io/react-auth";
export default function App({ Component, pageProps }: AppProps) {
return (
);
}
```
To use external Solana wallets, pass `toSolanaWalletConnectors()` to
`externalWallets`. See
[configuring connector chains](https://docs.privy.io/wallets/connectors/setup/configuring-external-connector-chains).
Use Privy’s modal and show a connected state when login completes.
```tsx theme={null}
"use client";
import { usePrivy } from "@privy-io/react-auth";
export default function ConnectButton() {
const { ready, authenticated, login, user } = usePrivy();
if (!ready) return
Loading...
;
if (authenticated) return
Connected
;
return ;
}
```
See the
[Privy Solana wallet docs](https://docs.privy.io/wallets/using-wallets/solana/send-a-transaction)
for transaction examples.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Turnkey
Source: https://pond.dflow.net/build/recipes/wallets/turnkey
How to add Turnkey to a Next.js + React app
Use Turnkey Embedded Wallet Kit to add authentication and embedded wallets to a
Next.js + React app.
## Prerequisites
Create a [Turnkey organization](https://docs.turnkey.com/getting-started/quickstart) in the [Turnkey dashboard](https://app.turnkey.com),
enable **Auth Proxy**, **email OTP**, and **passkeys**.
Copy your **Organization ID** and **Auth Proxy Config ID**.
## Step-by-step (Next.js + React)
Install the Turnkey React Wallet Kit in your Next.js app.
```bash theme={null}
npm install @turnkey/react-wallet-kit
```
Store your IDs in `.env.local` so your app can initialize Turnkey.
```bash theme={null}
NEXT_PUBLIC_ORGANIZATION_ID="your-org-id"
NEXT_PUBLIC_AUTH_PROXY_CONFIG_ID="your-auth-proxy-config-id"
```
Initialize Turnkey at the app root and include the wallet kit styles.
Create a client-side provider component, then wrap it in `app/layout.tsx`.
```tsx theme={null}
// app/providers.tsx
"use client";
import {
TurnkeyProvider,
TurnkeyProviderConfig,
} from "@turnkey/react-wallet-kit";
const turnkeyConfig: TurnkeyProviderConfig = {
organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
authProxyConfigId: process.env.NEXT_PUBLIC_AUTH_PROXY_CONFIG_ID!,
};
export function Providers({ children }: { children: React.ReactNode }) {
return (
console.error("Turnkey error:", error),
}}
>
{children}
);
}
```
```tsx theme={null}
// app/layout.tsx
import "@turnkey/react-wallet-kit/styles.css";
import { Providers } from "./providers";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
{children}
);
}
```
Wrap your app in `pages/_app.tsx`.
```tsx theme={null}
// pages/_app.tsx
import type { AppProps } from "next/app";
import "@turnkey/react-wallet-kit/styles.css";
import {
TurnkeyProvider,
TurnkeyProviderConfig,
} from "@turnkey/react-wallet-kit";
const turnkeyConfig: TurnkeyProviderConfig = {
organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
authProxyConfigId: process.env.NEXT_PUBLIC_AUTH_PROXY_CONFIG_ID!,
};
export default function App({ Component, pageProps }: AppProps) {
return (
console.error("Turnkey error:", error),
}}
>
);
}
```
Use Turnkey’s modal and show a connected state when login completes.
```tsx theme={null}
"use client";
import {
AuthState,
ClientState,
useTurnkey,
} from "@turnkey/react-wallet-kit";
export default function ConnectButton() {
const { handleLogin, authState, clientState } = useTurnkey();
if (clientState === undefined || clientState === ClientState.Loading) {
return
Loading...
;
}
if (clientState === ClientState.Error) {
return
Turnkey failed to initialize.
;
}
if (authState === AuthState.Authenticated) {
return
Connected
;
}
return ;
}
```
Use [theming](https://docs.turnkey.com/sdks/react/ui-customization) to customize
the Turnkey UI.
See [authentication](https://docs.turnkey.com/sdks/react/auth) for custom login
flows.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Intent Quote
Source: https://pond.dflow.net/build/trading-api/declarative/quote
GET /intent
API reference for GET /intent
`GET /intent` does not support Token-2022 mints. Use
[`GET /order`](/build/trading-api/order/order) instead.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Submit Intent Swap
Source: https://pond.dflow.net/build/trading-api/declarative/submit
POST /submit-intent
API reference for POST /submit-intent
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Quote
Source: https://pond.dflow.net/build/trading-api/imperative/quote
GET /quote
API reference for GET /quote
We recommend using the [`/order`](/build/trading-api/order/order) endpoint for new
integrations. This endpoint is still available but `/order` is the preferred
approach. For a code example, see the
[imperative trade recipe](/build/recipes/trading/imperative-trade).
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Create Swap
Source: https://pond.dflow.net/build/trading-api/imperative/swap
POST /swap
API reference for POST /swap
We recommend using the [`/order`](/build/trading-api/order/order) endpoint for new
integrations. This endpoint is still available but `/order` is the preferred
approach. For a code example, see the
[imperative trade recipe](/build/recipes/trading/imperative-trade).
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Create Swap Instructions
Source: https://pond.dflow.net/build/trading-api/imperative/swap-instructions
POST /swap-instructions
API reference for POST /swap-instructions
We recommend using the [`/order`](/build/trading-api/order/order) endpoint for new
integrations. This endpoint is still available but `/order` is the preferred
approach. For a code example, see the
[imperative trade recipe](/build/recipes/trading/imperative-trade).
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Introduction
Source: https://pond.dflow.net/build/trading-api/introduction
How to use the Trading API to trade crypto and prediction market outcomes.
Retrieve order information and check order status
Declarative Swaps are intent-based swaps that defer route calculation
Imperative Swaps give traders precise control over the route plan at
signature time
Utility endpoints for prediction markets
Get current priority fee estimates for trade requests
Stream priority fee estimate updates in real time
Get token information and lists with decimal precision
Get venue information and available trading venues
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Order
Source: https://pond.dflow.net/build/trading-api/order/order
GET /order
API reference for GET /order
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Order Status
Source: https://pond.dflow.net/build/trading-api/order/order-status
GET /order-status
API reference for GET /order-status
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Initialize Prediction Market
Source: https://pond.dflow.net/build/trading-api/prediction-market/prediction-market-init
GET /prediction-market-init
API reference for GET /prediction-market-init
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Priority Fees
Source: https://pond.dflow.net/build/trading-api/priority-fees/priority-fees
GET /priority-fees
API reference for GET /priority-fees
Returns the latest priority fee estimates for `medium`, `high`, and `very high`.
Response values are micro-lamports per compute unit.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Token List
Source: https://pond.dflow.net/build/trading-api/token/tokens
GET /tokens
API reference for GET /tokens
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Token List with Decimals
Source: https://pond.dflow.net/build/trading-api/token/tokens-with-decimals
GET /tokens-with-decimals
API reference for GET /tokens-with-decimals
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Get Venue List
Source: https://pond.dflow.net/build/trading-api/venues/venues
GET /venues
API reference for GET /venues
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Websockets Overview
Source: https://pond.dflow.net/build/trading-api/websockets/overview
Stream real-time Trading API updates via WebSocket
The Trading API WebSocket currently supports one stream: priority fee updates.
Looking for prediction market streams (`prices`, `trades`, `orderbook`)? See
the [Metadata API WebSockets overview](/build/metadata-api/websockets/overview).
## Connection
The dev Trading API WebSocket URL is:
```
wss://dev-quote-api.dflow.net/priority-fees/stream
```
For production, use your Trading API host with `wss:` and the
`/priority-fees/stream` path:
```
wss:///priority-fees/stream
```
## Stream
| Stream | Description |
| --------------- | --------------------------------------- |
| `priority-fees` | Real-time priority fee estimate updates |
Stream priority fee estimates without polling
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Priority Fees Stream
Source: https://pond.dflow.net/build/trading-api/websockets/priority-fees-stream
GET /priority-fees/stream
Stream Trading API priority fee estimates over WebSocket
Use this stream to receive real-time priority fee estimate updates.
No subscribe message is required. Connect to the endpoint and start reading
messages.
## Connection
See the [Websockets Overview](/build/trading-api/websockets/overview#connection)
for endpoint details.
## Message Format
Each message is a JSON object with the same shape as
[`GET /priority-fees`](/build/trading-api/priority-fees/priority-fees):
```json theme={null}
{
"mediumMicroLamports": 100000,
"highMicroLamports": 150000,
"veryHighMicroLamports": 220000
}
```
## Example (TypeScript)
```typescript theme={null}
import WebSocket from "ws";
const WS_URL = "wss://dev-quote-api.dflow.net/priority-fees/stream";
const ws = new WebSocket(WS_URL);
ws.onopen = () => {
console.log("Connected — waiting for priority fee updates");
};
ws.onmessage = (event) => {
const fees = JSON.parse(event.data.toString());
console.log("Priority fees (micro-lamports/CU):", fees);
};
```
## Related
* [Websockets Overview](/build/trading-api/websockets/overview)
* [GET /priority-fees](/build/trading-api/priority-fees/priority-fees)
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Platform Fees
Source: https://pond.dflow.net/build/trading/platform-fees
How to apply platform fees to trades
Use platform fees to monetize DFlow integrations by collecting fees on trades executed through applications. Add platform fees by setting fee parameters on [Trade API requests](/build/trading-api/order/order).
Users pay platform fees only when a trade completes successfully. Platform fees do not affect quoting, routing, slippage checks, or execution behavior.
When a trade completes, the platform fee is transferred to a builder-controlled fee account.
From a user’s perspective:
* Fees apply only on successful trades.
* Fees change net proceeds, not execution.
## Fee Models
Builders choose one of two fee models.
### Fixed Platform Fees
Charge a fixed percentage of the trade amount.
* Fees are specified in basis points (bps).
* 1 bps = 0.01%.
* Example: `platformFeeBps: 50` means a 0.5% fee.
Builders decide whether the fee is collected from the input token or output token using `platformFeeMode`.
### Dynamic Platform Fees (Prediction Markets)
Builders charge a price-dependent fee on prediction market outcome token trades by setting `platformFeeScale`.
DFlow calculates the fee as:
```
k * p * (1 - p) * c
```
Where:
* `k` is `platformFeeScale` with 3 decimals of precision (example: `50` means `0.050`).
* `p` is the all-in price (includes all fees + filled price).
* `c` is the contract size.
Users pay no platform fee when redeeming a winning outcome (`p = 1`). This means apps do not charge a platform fee for outcome token redemption.
## Platform Fee Parameters
Configure platform fees using three parameters.
### platformFeeMode
Use `platformFeeMode` to choose which token users pay the fee in:
* `outputMint` (default): fee is collected from the output token.
* `inputMint`: fee is collected from the input token.
For [imperative trades](/learn/imperative-trades), they can be paid in either the `inputMint` or `outputMint`.
For [declarative trades](/learn/declarative-trades), they can currently only be paid in the `outputMint`.
For [prediction markets outcome token trades](/learn/prediction-markets), they can only be paid in the `settlementMint`.
### platformFeeBps
Use `platformFeeBps` to set a fixed platform fee in basis points.
* The fee is calculated as a percentage of the trade amount.
* The fee is collected from the input or output token based on `platformFeeMode`.
### platformFeeScale
Use `platformFeeScale` only for outcome token trades to enable dynamic fees.
* The fee scales with price and contract size using the formula above.
* The fee is zero at redemption for winning outcomes (`p = 1`).
## Fee Accounts
Platform fees are transferred to a builder-controlled token account. You need a separate token account (ATA) for each token you collect fees in. For example, if your app collects fees in both USDC and SOL, you need a USDC fee account and a SOL fee account.
### Using `feeAccount`
Pass `feeAccount` to specify the token account that receives the fee. The account must:
* Be a valid SPL token account for the token being collected.
* Already exist before the trade executes.
The token must match the fee mode:
* Input token account when collecting from `inputMint`
* Output token account when collecting from `outputMint`
* Settlement token account when collecting from prediction market outcome token trades
## How Platform Fees Affect Trades
Platform fees change net economics, not trade behavior.
* Routing stays the same.
* Slippage enforcement stays the same.
* Execution timing stays the same.
If a trade fails, users pay no platform fee.
Only specify a nonzero platform fee if you will actually collect the fee at execution time. When the API receives a nonzero `platformFeeBps`, it factors the fee into slippage tolerance calculations. If the fee is declared in the request but not collected onchain, the slippage budget is effectively wasted on a fee that never gets taken, resulting in suboptimal pricing for your users.
## When To Use Platform Fees
Use platform fees if you want to:
* Monetize trading volume.
* Fund product development.
* Align incentives with usage.
## Code Recipes
* [Platform fee recipe](/build/recipes/trading/platform-fees).
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Priority Fees
Source: https://pond.dflow.net/build/trading/priority-fees
How priority fees affect trade execution
Priority fees affect **when a trade executes**, not **how it executes**.
They are additional fees paid to Solana validators to increase the likelihood that a transaction is included quickly during periods of network congestion. Higher priority fees improve execution speed. Lower fees reduce cost but may delay execution.
Priority fees do **not** change routing, slippage checks, or trade semantics. They only influence transaction ordering.
## How DFlow Handles Priority Fees
DFlow supports two ways to set priority fees:
* **Max Priority Fee**
* **Exact Priority Fee**
Choose between them based on whether you prefer **cost predictability** or **adaptive execution speed**.
## Priority Fee Estimates API
If you want current fee estimates, use:
* [GET /priority-fees](/build/trading-api/priority-fees/priority-fees) for a snapshot.
* [GET /priority-fees/stream](/build/trading-api/websockets/priority-fees-stream) for real-time updates over WebSocket.
## Max Priority Fee
Use the Max Priority Fee to allow DFlow to **dynamically choose an optimal priority fee**, capped at a pre-defined maximum.
This approach balances execution speed with cost. DFlow reacts to current network conditions but never exceeds the maximum you set.
### How It Works
Specify:
* A **priority level** (`medium`, `high`, `veryHigh`).
* A **maximum fee** (`maxLamports`).
DFlow selects the lowest fee likely to achieve the requested priority, capped by your maximum.
If no priority fee parameters are provided, DFlow defaults to automatic priority fees capped at **0.005 SOL**.
### When Max Priority Fee Makes Sense
Use Max Priority Fee when:
* Execution speed matters.
* Network conditions are unpredictable.
* You want protection against overpaying during congestion.
This is the recommended default for most user-facing trading flows.
## Exact Priority Fee
Exact Priority Fee uses a **fixed fee amount** for every trade.
DFlow applies the specified fee regardless of network conditions. No adjustments are made.
### How It Works
Provide a fixed priority fee in lamports. That fee is always used.
When using intent-based endpoints, builders must include the **base processing fee (10,000 lamports)** in addition to the desired priority fee.
If the network requires higher fees than the amount specified, the trade may be delayed or fail.
### When Exact Priority Fee Makes Sense
Use Exact Priority Fees when:
* Cost predictability is critical.
* Fees must be strictly budgeted.
* Delayed execution is acceptable.
This mode is best suited for automation, testing, or environments with strict fee constraints.
## What Priority Fees Do *Not* Affect
Priority fees do **not**:
* Change routing decisions.
* Bypass slippage checks.
* Alter trade execution logic.
* Guarantee execution success.
They only influence how quickly a transaction is considered for inclusion.
## Code Recipes
* [Priority fee recipe](/build/recipes/trading/priority-fees).
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Slippage Tolerance
Source: https://pond.dflow.net/build/trading/slippage-tolerance
How slippage works and how to control it in Trading API requests
Slippage is the difference between the quoted price and
the final execution price. On Solana, prices can move between quote and execution
because transactions are processed in blocks and liquidity shifts rapidly. A
higher tolerance increases execution probability; a lower tolerance tightens
price protection.
Builders have two options for slippage tolerance:
* **Auto slippage**: DFlow chooses the tolerance dynamically.
* **Custom slippage**: You set the tolerance explicitly.
## Auto Slippage Tolerance
With auto slippage, DFlow determines the optimal slippage based on market
conditions so trades have a high probability of success while maintaining price
protection.
To use auto slippage, set `slippageBps=auto` on either of the following API routes:
* [`GET /order`](/build/trading-api/order/order)
* [`GET /intent`](/build/trading-api/declarative/quote)
Auto slippage is calculated server-side by the DFlow Aggregator and updates
continuously based on current onchain conditions.
## Custom Slippage Tolerance
Custom slippage gives traders direct control over the maximum price deviation
they are willing to accept.
To use custom slippage, set `slippageBps` to a non-negative integer (u16) on either of the following API routes:
* [`GET /order`](/build/trading-api/order/order)
* [`GET /intent`](/build/trading-api/declarative/quote).
The value is in basis points (1 bp = 0.01%).
Setting slippage too low can cause trades to fail during high volatility or
when liquidity is thin.
## Sequence of Events
1. You set slippage tolerance (auto or custom).
2. You request an order or intent quote.
3. DFlow validates the execution price against your tolerance.
4. If the tolerance is met, the trade executes; otherwise it fails safely.
## API Routes
* [GET /order](/build/trading-api/order/order)
* [GET /intent](/build/trading-api/declarative/quote)
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Sponsored Swaps
Source: https://pond.dflow.net/build/trading/sponsored-swaps
How to implement gasless swaps where a sponsor covers transaction fees
Use sponsored swaps to build gasless trading features where users swap tokens without holding SOL for fees. A **sponsor** pays the transaction fee and token account creation costs on the user's behalf.
To create a sponsored swap, pass the `sponsor` parameter with the sponsor's wallet address on a [Trade API request](/build/trading-api/order/order). Both the user and sponsor must sign the resulting transaction.
## Why Use User-Executed Sponsored Swaps
* **Smaller transactions.** Eliminates the input transfer to the sponsor and output transfer back to the user, reducing overall transaction size.
* **Simpler transaction structure.** The user swaps directly from their own token accounts in a single step.
## Execution Modes
Execution modes determine who performs the swap.
### Sponsor Executes (Default)
The sponsor performs the swap on the user's behalf:
1. User transfers input tokens to sponsor.
2. Sponsor executes the swap using their token accounts.
3. Sponsor transfers output tokens to user.
### User Executes
The user performs the swap directly using their own token accounts. The sponsor still pays the transaction fee and token account creation costs.
## Parameters
### sponsor
The sponsor's wallet address. When specified, the sponsor pays the transaction fee and token account creation costs. Cannot be specified alongside `predictionMarketInitPayer`. Base58-encoded.
### sponsoredSwap
Set to `true` to indicate the swap will be sponsored. This ensures the quote accounts for the correct transaction structure and fees based on the execution mode. Not needed on `/order` or `/swap` — those endpoints infer sponsorship from the `sponsor` parameter.
### sponsorExec
Choose who executes the swap in a sponsored transaction.
| Value | Executor | Description |
| ---------------- | -------- | ----------------------------------------------------- |
| `true` (default) | Sponsor | Sponsor executes the swap using their token accounts |
| `false` | User | User executes the swap using their own token accounts |
Pass this parameter on three endpoints:
* [`GET /order`](/build/trading-api/order/order) — query parameter, used when `sponsor` is specified.
* [`GET /quote`](/build/trading-api/imperative/quote) — query parameter, used when `sponsoredSwap` is `true`.
* [`POST /swap`](/build/trading-api/imperative/swap) — request body field, used when `sponsor` is specified.
## Code Examples
```typescript theme={null}
const SPONSOR_ADDRESS = "SPONSOR_WALLET_ADDRESS";
const params = new URLSearchParams({
inputMint: "So11111111111111111111111111111111111111112",
outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
amount: "1000000000",
userPublicKey: userKeypair.publicKey.toBase58(),
sponsor: SPONSOR_ADDRESS,
sponsorExec: "false", // user executes; omit or set "true" for sponsor execution
});
const headers: HeadersInit = {};
if (process.env.DFLOW_API_KEY) {
headers["x-api-key"] = process.env.DFLOW_API_KEY;
}
const orderResponse = await fetch(
`${API_BASE_URL}/order?${params.toString()}`,
{ headers }
).then((x) => x.json());
// Both user and sponsor must sign
const tx = VersionedTransaction.deserialize(
Buffer.from(orderResponse.transaction, "base64")
);
tx.sign([userKeypair, sponsorKeypair]);
const signature = await connection.sendRawTransaction(tx.serialize());
await connection.confirmTransaction(signature, "confirmed");
```
```typescript theme={null}
const params = new URLSearchParams({
inputMint: "So11111111111111111111111111111111111111112",
outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
amount: "1000000000",
sponsoredSwap: "true", // required on /quote to signal sponsorship
sponsorExec: "false",
});
const quoteResponse = await fetch(
`${API_BASE_URL}/quote?${params.toString()}`,
{ headers }
).then((x) => x.json());
```
```typescript theme={null}
const swapResponse = await fetch(`${API_BASE_URL}/swap`, {
method: "POST",
headers: { "Content-Type": "application/json", ...headers },
body: JSON.stringify({
quoteResponse,
userPublicKey: userKeypair.publicKey.toBase58(),
sponsor: "SPONSOR_WALLET_ADDRESS",
sponsorExec: false,
}),
}).then((x) => x.json());
// Both user and sponsor must sign
const tx = VersionedTransaction.deserialize(
Buffer.from(swapResponse.swapTransaction, "base64")
);
tx.sign([userKeypair, sponsorKeypair]);
const signature = await connection.sendRawTransaction(tx.serialize());
await connection.confirmTransaction(signature, "confirmed");
```
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Trading Data Model
Source: https://pond.dflow.net/build/trading/trade-api-data-model
How trading data is structured around `/order` requests
Use this page as a reference for the key objects returned by the [`/order
`](/build/trading-api/order/order) endpoint and where each one appears in the request/response flow.
This page focuses on **imperative** trades.
We recommend using the `/order` endpoint for new integrations. The `/quote`, `/swap`, and
`/swap-instructions` endpoints are still available but `/order` is the preferred approach.
## High-Level Model
You request an **Order**, which returns a **Quote** and, if `userPublicKey` is
provided, a **Transaction** to sign and submit. The response may include a
**routePlan** (one or more legs) and an **executionMode** (sync or async).
```mermaid theme={null}
flowchart TD
OrderRequest -->|returns| OrderResponse
OrderResponse -->|may_include| Transaction
OrderResponse -->|may_include| RoutePlanLeg
Transaction -->|submit| SolanaRPC
SolanaRPC -->|track| OrderStatus
```
## Example (Trade SOL → USDC)
**Input mint**: SOL\
**Output mint**: USDC
Flow:
1. Call [`GET /order`](/build/trading-api/order/order) with `inputMint`,
`outputMint`, and `amount`.
2. Inspect `priceImpactPct`, `routePlan`, and `executionMode`.
3. If `transaction` is returned, sign it and send it to Solana.
4. For async execution, poll [`GET /order-status`](/build/trading-api/order/order-status).
## Entity Reference
### Order Request (Query Parameters)
Core parameters:
| Field | Type | Notes |
| ----------------------------- | ------------------- | ------------------------------------------ |
| `inputMint` | string | Base58 input mint |
| `outputMint` | string | Base58 output mint |
| `amount` | integer | Input amount (scaled integer) |
| `userPublicKey` | string | Wallet; includes `transaction` in response |
| `slippageBps` | integer \| `"auto"` | Max allowed slippage |
| `predictionMarketSlippageBps` | integer \| `"auto"` | Slippage for prediction orders |
| `priceImpactTolerancePct` | integer | Max price impact % override |
Routing controls:
| Field | Type | Notes |
| ------------------ | ------- | ---------------------------------------- |
| `dexes` | string | Comma-separated include list |
| `excludeDexes` | string | Comma-separated exclude list |
| `onlyDirectRoutes` | boolean | Force single-leg routes |
| `maxRouteLength` | integer | Max legs (ignored if `onlyDirectRoutes`) |
| `onlyJitRoutes` | boolean | Force JIT routes |
| `forJitoBundle` | boolean | Routes compatible with Jito bundles |
Execution controls:
| Field | Type | Notes |
| -------------------- | ------- | ----------------------------------- |
| `allowSyncExec` | boolean | Allow sync execution |
| `allowAsyncExec` | boolean | Allow async execution |
| `restrictRevertMint` | boolean | Input must be revert mint for async |
Fees and accounts:
| Field | Type | Notes |
| ---------------------------- | ------- | ---------------------------------------- |
| `platformFeeMode` | enum | Fee collected from input/output |
| `platformFeeBps` | integer | Platform fee in bps |
| `platformFeeScale` | integer | Prediction market fee scale (3 decimals) |
| `feeAccount` | string | Token account for platform fees |
| `positiveSlippageFeeAccount` | string | Account for positive slippage |
| `positiveSlippageLimitPct` | integer | Cap on positive slippage fee |
| `sponsor` | string | Sponsor wallet (gasless) |
| `destinationTokenAccount` | string | Output token account |
| `destinationWallet` | string | Output wallet (ATA if needed) |
| `revertWallet` | string | Revert wallet for async orders |
In `POST /swap`, if you set `destinationTokenAccount.address` and want native SOL output, pass the wallet address (owner) instead of the wallet's WSOL associated token account address.
Transaction configuration:
| Field | Type | Notes |
| -------------------------------------- | ----------------- | ------------------------------ |
| `wrapAndUnwrapSol` | boolean | Use native SOL if true |
| `prioritizationFeeLamports` | integer \| enum | Priority fee or level |
| `computeUnitPriceMicroLamports` | integer | CU price (mutually exclusive) |
| `dynamicComputeUnitLimit` | boolean | Simulate to determine CU limit |
| `includeJitoSandwichMitigationAccount` | boolean \| string | Jito mitigation |
Prediction market parameters:
| Field | Type | Notes |
| ----------------------------- | ------ | --------------------------------- |
| `predictionMarketInitPayer` | string | Pays market init if uninitialized |
| `outcomeAccountRentRecipient` | string | Rent recipient on close |
### Order Response (OrderResponse)
| Field | Type | Notes |
| ----------------------------------- | -------------- | --------------------------------------- |
| `inputMint` | string | Base58 input mint |
| `inAmount` | string | Max input amount (scaled integer) |
| `outputMint` | string | Base58 output mint |
| `outAmount` | string | Expected output amount (scaled integer) |
| `otherAmountThreshold` | string | Min output after fees |
| `minOutAmount` | string | Same as `otherAmountThreshold` |
| `slippageBps` | integer | Max slippage in bps |
| `predictionMarketSlippageBps` | integer | Prediction order slippage |
| `priceImpactPct` | string | Estimated price impact |
| `contextSlot` | integer | Slot at evaluation time |
| `executionMode` | enum | `sync` or `async` |
| `routePlan` | array | Route legs (sync and known routes) |
| `platformFee` | object \| null | Platform fee if applied |
| `initPredictionMarketCost` | integer | Lamports to init market |
| `predictionMarketInitPayerMustSign` | boolean | Init payer signature required |
| `revertMint` | string | Revert mint for async orders |
| `transaction` | string | Base64 tx to sign/send |
| `lastValidBlockHeight` | integer | Last valid block height |
| `computeUnitLimit` | integer | Compute unit limit |
| `prioritizationFeeLamports` | integer | Priority fee in lamports |
| `prioritizationType` | object | Priority fee type |
### Route Leg (RoutePlanLeg)
Each leg is either a **DynamicRoutePlanLeg** or **SingleMarketRoutePlanLeg**.
Common fields:
| Field | Type | Notes |
| -------------------- | ------- | ---------------------------- |
| `venue` | string | Venue for the leg |
| `marketKey` | string | Market key for venue |
| `inputMint` | string | Input mint |
| `outputMint` | string | Output mint |
| `inAmount` | string | Max input amount |
| `outAmount` | string | Expected output amount |
| `inputMintDecimals` | integer | Input decimals |
| `outputMintDecimals` | integer | Output decimals |
| `data` | string | Present only on dynamic legs |
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Contact
Source: https://pond.dflow.net/contact
Get in touch with the DFlow team
## Email
For partnership inquiries or general questions, reach out at [hello@dflow.net](mailto:hello@dflow.net).
## Developer support
For technical questions, the fastest way to get help is through our community channels.
Connect with other developers and get help from the DFlow team.
Join the DFlow Dev Notifications Telegram group to stay in the loop on new features and announcements.
# Welcome to DFlow
Source: https://pond.dflow.net/introduction
DFlow is a trading protocol that enables traders to exchange value across spot and prediction markets natively on Solana.
Build with DFlow
Build institution-grade trading experiences across spot and prediction
markets natively on Solana with a single, unified platform.
Pick the best place to start based on what you need right now:
Follow end-to-end recipes for building trading and prediction market
apps with DFlow.
Understand how routing, concurrency, swaps, slippage, and priority fees work
under the hood.
Explore endpoints, schemas, and examples for submitting and managing trades
through the unified Trade API.
Discover markets, access historical data, and trade outcome tokens with
comprehensive prediction market metadata.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Concurrent Liquidity Programs
Source: https://pond.dflow.net/learn/clp
How Concurrent Liquidity Programs enable offchain liquidity
With Concurrent Liquidity Programs (CLPs) users can execute onchain trades against offchain liquidity.
Instead of executing a trade atomically against onchain liquidity, users submit a limit-priced intent onchain. Liquidity providers fill that intent asynchronously through follow-up transactions.
CLPs separate **trade intent** from **trade fulfillment**.
### Why CLPs Exist
On Solana, users can only trade directly against liquidity that exists onchain.
CLPs make offchain liquidity accessible without requiring users to give up self-custody or move funds offchain. Users keep SPL tokens in their wallet while liquidity providers act on onchain intent.
This expands available liquidity beyond what atomic trades alone can support.
For builders, this makes it possible to integrate professional liquidity providers without custodial risk.
### CLPs and Prediction Markets
DFlow uses CLPs to execute **prediction market trades**, where outcome tokens are filled asynchronously by liquidity providers after a user submits limit-priced intent onchain.
This execution model makes it possible to trade [prediction market](/learn/prediction-markets) outcomes using offchain liquidity while keeping positions tokenized on Solana.
### CLP Trade Lifecycle
A typical CLP trade follows this flow:
1. A user submits limit-priced trade intent
2. Liquidity providers observe the open intent
3. Fill transactions execute over time
4. The user’s position increases, decreases, or closes
The trade completes when the intent is fully satisfied.
### Liquidity Providers
Liquidity providers operate offchain.
They monitor onchain CLP state and submit fill transactions when pricing conditions are favorable. They never custody user funds.
### Takers
Takers are users who initiate CLP trades.
They write trade intent onchain and receive fills asynchronously as liquidity providers act on that intent.
### CLP Execution Model
CLP trades execute across multiple transactions.
The initial transaction expresses trade intent. One or more subsequent transactions perform fills. Because execution is spread over time, CLP trades are **async trades**.
### Increasing and Reducing Positions
To [**increase** a position](/build/recipes/prediction-markets/increase-position), a user writes a limit price and trade side onchain. A liquidity provider fills the position at that price or better by minting SPL tokens that represent the position.
To [**decrease** a position](/build/recipes/prediction-markets/decrease-position), a user writes a limit price and trade side. A liquidity provider transfers value to the user equivalent to the position reduced at the limit price or better.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Declarative Trades
Source: https://pond.dflow.net/learn/declarative-trades
How declarative trades work and why they improve execution
With declarative trades, users define **what they want to trade (an intent)**, while DFlow determines **how the trade executes** as close to execution time as possible. This has greater sandwich protection, is more flexible than [imperative trades](/learn/imperative-trades), and helps users get the best prices possible.
Instead of committing to a fixed route at quote time, users submit a trade intent. Final routing decisions are evaluated at execution time using current onchain prices.
## What Makes a Trade Declarative
In a declarative trade, users do not specify an execution path.
They specify:
* The assets to trade.
* The minimum acceptable outcome.
* The slippage tolerance.
DFlow is responsible for selecting the best available route that satisfies those constraints at execution time.
This separates **trade constraints** from **execution mechanics**.
## How Declarative Trades Execute
Declarative trades use an **open-order + fill structure**, executed using **Jito bundles**.
A Jito bundle groups multiple transactions for ordered, atomic execution within the same slot. If any transaction in the bundle fails, none are processed.
```mermaid theme={null}
flowchart LR
A[Request /intent] --> B[Sign open transaction]
B --> C[Submit intent]
C --> D[Monitor status]
```
Here’s how it works:
1. The user signs an open order transaction signaling an intent to trade.
2. Funds are temporarily escrowed onchain in the [DFlow Swap Orchestrator contract](https://solscan.io/account/DF1ow3DqMj3HvTj8i8J9yM2hE9hCrLLXpdbaKZu4ZPnz).
3. The user then signs the open order transaction and submits it to the DFlow Aggregator to be filled.
4. Routing is evaluated immediately before execution.
5. The open-order and fill transactions execute together as a bundle.
If any transaction fails, **no state changes are applied**.
## Why Declarative Trades Reduce Slippage
Slippage occurs when prices change between quote and execution.
Declarative trades reduce slippage by:
* Delaying route finalization until execution.
* Evaluating prices onchain immediately before execution.
* Avoiding stale routes embedded at quote time.
Instead of following a fixed plan, the trade adapts while still enforcing user-defined limits.
## Why Declarative Trades Improve Reliability
Many failed trades occur when prices move beyond slippage tolerance before execution.
Declarative trades improve reliability by:
* Reducing price drift between routing and execution.
* Lowering the chance of slippage violations.
* Avoiding retries and wasted fees.
This is especially important in fast-moving or latency-sensitive markets.
## Why Declarative Trades Reduce Sandwich Risk
Sandwich attacks exploit the gap between when a route is revealed and when execution happens.
Declarative trades reduce this risk by avoiding fixed routes at quote time. Because routing is finalized at execution and submitted as a bundled transaction, there is less opportunity for third parties to react to a known path and insert transactions around it.
This does not eliminate sandwich risk entirely, but it significantly reduces exposure compared to trades with pre-committed routes.
## When Declarative Trades Make Sense
Declarative trades are a good fit when:
* Prices move quickly.
* Liquidity is fragmented.
* Minimizing slippage matters more than route control.
* Execution reliability is critical.
They are the default choice for user-facing trading flows.
## Code Recipes
* [Declarative trading recipe](/build/recipes/trading/declarative-trade).
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# How Trading Works on DFlow
Source: https://pond.dflow.net/learn/how-trading-works
How trading works on DFlow
DFlow has a single, unified trading API that builders can use to trade different asset types through the same interface. Today, users can trade spot crypto and prediction market outcomes.
From an app’s perspective, trading follows the same high-level flow: request a quote, present it to a user, and submit a signed transaction for execution. What changes across asset types is the underlying trade mechanics, not the integration surface.
DFlow supports two trade types: **[declarative trades](/learn/declarative-trades)** and **[imperative trades](/learn/imperative-trades)**.
Choose [**declarative trades**](/learn/declarative-trades) when adaptability and execution quality matter more than enforcing a specific route.
Choose [**imperative trades**](/learn/imperative-trades) when deterministic routing, explicit venue control, or strategy-driven execution matter more than adaptation.
When trading spot crypto, builders can use either declarative or imperative trades, and execution is synchronous. Prediction market trades use imperative async trades backed by [Concurrent Liquidity Programs](/learn/clp).
## TLDR; Declarative vs Imperative Trades
* [Declarative trades](/learn/declarative-trades) define **acceptable outcomes**.
* [Imperative trades](/learn/imperative-trades) define **exact execution paths**.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Imperative Trades
Source: https://pond.dflow.net/learn/imperative-trades
How to execute imperative trades with full routing control
Imperative trades, in contrast to [Declarative trades](/learn/declarative-trades), give traders precise control over the route plan at signature time.
## How Imperative Trades Work
In an imperative trade, the app specifies the execution plan before the user signs the transaction.
```mermaid theme={null}
flowchart LR
A[Request /order] --> B[Sign transaction]
B --> C[Submit to RPC]
C --> D[Confirm status]
```
Here’s how it works:
1. The app requests a order.
2. The user signs and submits the order to a Solana RPC.
3. Execution follows the specified path exactly.
## When Imperative Trades Make Sense
Imperative trades are a good fit when an app needs:
* To modify the swap transaction, which enables composability.
* Deterministic execution paths.
* Tight control over venue selection.
* Predictable behavior for automation or compliance.
* Integration with external systems that assume fixed routes.
Builders commonly use imperative trades for:
* Strategy-driven or rules-based trading.
* Research and testing.
* Products where routing logic is part of the value proposition.
## Code Recipes
* [Imperative trading recipe](/build/recipes/trading/imperative-trade).
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# JIT Routing
Source: https://pond.dflow.net/learn/jit-routing
How JIT routing updates trade execution onchain
JIT Routing (Just-in-Time Routing) is DFlow’s onchain routing mechanism that updates trade routes at execution time to find the best possible prices.
Traditional Solana aggregators compute routes offchain and embed a fixed path into the transaction. Once signed, that route cannot change. If prices move before execution, the transaction either executes or fails due to slippage limits.
JIT Routing moves part of the routing decision onchain. The swap transaction contains conditional logic that allows the router to select between liquidity sources during execution, based on current onchain prices.
### When JIT Routing Is Used
JIT routing engages automatically when the router determines it is optimal.
### Execution Flow
1. **Quote time (offchain)**
* DFlow computes an optimal route using current market data.
* The route may include prop AMMs and fallback venues.
2. **Transaction construction**
* The transaction embeds conditional instructions.
* These instructions allow branching between liquidity sources.
3. **Execution time (onchain)**
* Before executing, the program checks the current onchain price.
* If the price is within acceptable bounds, the original leg is executed.
* If the price has moved beyond a threshold, the router switches to an alternative venue.
* All decisions occur within the same transaction.
The route is finalized at execution, not at quote time.
### Key Properties
* **Onchain decision making**
Routing decisions are made by the program during execution, not by offchain infrastructure.
* **Single transaction**
Rerouting does not require resubmission or multiple transactions.
* **Deterministic constraints**
All possible branches are known and encoded at transaction construction time.
* **No user interaction changes**
Users still request a quote and sign a transaction as usual.
### Benefits for Builders
* **Lower realized slippage**
Execution reflects current prices instead of stale quotes.
* **Higher success rates**
Fewer transactions fail due to price movement exceeding slippage tolerance.
* **Reduced need for wide slippage limits**
Less exposure to adverse execution caused by conservative slippage settings.
### Comparison to Static Routing
| Aspect | Static Routing | JIT Routing |
| ---------------------------- | --------------- | -------------------- |
| Route selection | Offchain, fixed | Onchain, conditional |
| Reaction to price changes | None | Immediate |
| Failure risk in fast markets | High | Lower |
### Availability
JIT Routing is enabled automatically for eligible routes when using the DFlow Trading API. No additional parameters are required from builders.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Liquidity and Venues
Source: https://pond.dflow.net/learn/liquidity-venues
How DFlow routes liquidity across venues
DFlow sources liquidity through multiple venues on Solana.
This includes onchain AMMs, Prop AMMs, order-book-style venues, and other onchain venues. DFlow treats these venues as interchangeable sources of liquidity and exposes them through a single execution interface. DFlow uses reliable DEXs like Raydium, Orca, Phoenix, Lifinity, and many more.
For users, this typically results in **better realized prices** than routing through a single venue or a fixed path.
For builders, this means better execution quality without hard-coding venue logic or price comparisons.
A full list of venues is available from the [Venues API Endpoint](/build/trading-api/venues/venues).
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Prediction Markets
Source: https://pond.dflow.net/learn/prediction-markets
How prediction markets work on DFlow
## What Prediction Markets Are
A prediction market lets users trade on the outcome of a real-world event, expressed as a **yes** or **no** question.
For example: *Will the Boston Red Sox win the World Series?* Users trade either **yes** or **no**.
Outcomes are always binary. Even in a matchup like Boston Red Sox vs. New York Yankees, the market does not ask “Which team will win?” Instead, each team has its own **yes/no** market, such as “Will the Boston Red Sox win the World Series?” and “Will the New York Yankees win the World Series?”
The market price acts like a probability-like signal because it reflects how traders are entering positions under financial incentives.
In practice, users do the same things they do in spot markets: discover markets, view prices, place trades, and manage positions. What changes is the asset being traded, and the skill set that can produce an edge.
Spot trading often rewards understanding an asset and its market structure. Prediction markets can reward different strengths: interpreting news quickly, reasoning about incentives, estimating odds, and understanding how resolution criteria translate into payouts.
## Why You Should Care
In 2025, total volume across major [prediction market platforms reached **about \$44B**](https://www.forbes.com/sites/boazsobrado/2025/12/16/how-prediction-markets-actually-grew-in-2025/?utm_source=chatgpt.com), with most volume split between Polymarket and Kalshi.
Prediction markets to turn real-world events into tradable assets. This creates new opportunities for trading UX, portfolio UX, and post-event settlement UX without inventing a new interaction model.
## Why Tokenization Matters
Tokenizing prediction markets on Solana makes them usable inside the rest of the onchain economy.
Instead of keeping positions inside a single venue (Kalshi), builders can treat prediction market positions like other SPL tokens and unlock new product designs. For example, builders can create apps where users:
* Trade outcomes inside a Solana wallet.
* Track positions alongside spot holdings.
* Route trades through Solana trading primitives.
* Use outcome tokens in other onchain apps while markets are open.
This is the main reason builders often prefer a tokenized integration over direct trading with Kalshi.
## How Prices Map To Probabilities
Prediction market prices are often read as probabilities because they reflect how traders are willing to position under risk.
If a “Yes” outcome is trading at 60, traders are collectively pricing that outcome as roughly a 60% chance. If new information appears, traders adjust their positions, and the price moves.
This makes prices easy to reason about: they update as information changes, and they summarize many independent views into a single signal.
[Vitalik Buterin has described prediction markets as useful because they reward being correct and penalize being wrong](https://vitalik.ca/general/2021/08/16/prediction_markets.html), which helps prices converge toward accurate expectations over time.
## How DFlow Supports Prediction Markets Today
DFlow’s Prediction Markets API gives builders programmatic access to **tokenized Kalshi markets on Solana**, so apps can let users trade prediction markets using the same trading primitives used elsewhere on Solana.
Kalshi is a U.S. prediction market platform that offers event contracts and operates under CFTC oversight.
## Outcome Tokens
Outcome tokens are tokens that represent positions in a prediction market outcome.
A market typically maps to outcome tokens like “Yes” and “No.” Users can buy, sell, and hold these tokens while the market is open.
From a user’s perspective, they behave like other tokens:
* Users can trade them again before resolution.
* Users can hold them as a position.
* Users can redeem after resolution.
For builders, this maps prediction markets to a familiar token model: balances, positions, transfers, and redemption flows.
## How Markets Resolve
Every market resolves to an outcome.
Resolution is the transition from “trade” to “settle”:
* One side becomes redeemable.
* The other side becomes worthless.
This enables both pre-event trading and post-event payout UX in the same app.
## How Settlement And Redemption Work
After resolution, users redeem outcome tokens for value according to the market result.
This creates a second phase of UX that does not exist in spot trading:
* Redemption flows.
* Position closeout UX.
* History and receipts UX.
* Closing [outcome token accounts to reclaim rent](/build/recipes/prediction-markets/close-outcome-token-accounts).
## Entering a Position in a Prediction Market
Entering a prediction market position this flow:
1. A user discovers a prediction market.
2. The user selects an outcome to trade.
3. A quote is requested for that outcome.
4. The user signs and submits a trade.
5. The user receives an outcome token representing their position.
From this point on, outcome tokens behave like other SPL tokens until the market resolves.
## What Builders Can Build
* Market discovery (categories, search, trending).
* Market detail pages (price chart, liquidity, positions).
* Trading UX for outcome tokens (buy/sell, limits, slippage).
* Portfolio + PnL views across spot and prediction positions.
* Automation (alerts, conditional trades, rebalancing).
* Post-resolution redemption UX and receipts.
* Composable apps that treat outcome tokens like other assets (for example, collateral or lending primitives).
## KYC Requirements
Buying outcome tokens requires Proof verification. See [Understanding KYC for Prediction Markets](/build/prediction-markets/kyc) for details on which wallets need verification, how to handle unverified users, and how quoting works without KYC.
## Regulatory and Compliance Requirements
Prediction market trading through Kalshi is subject to U.S. regulatory
requirements.
Builders integrating tokenized Kalshi markets are responsible for ensuring
their applications comply with Kalshi’s member obligations. This includes
enforcing **geo-blocking for users in the United States and other restricted
jurisdictions**. Kalshi operates as a CFTC-regulated exchange, and access to
its markets is prohibited from certain countries and regions.
Access must be blocked from the **United States** and the following
jurisdictions:
Afghanistan, Algeria, Angola, Australia, Belarus, Belgium, Bolivia, Bulgaria,
Burkina Faso, Cameroon, Canada, Central African Republic, Côte d’Ivoire, Cuba,
Democratic Republic of the Congo, Ethiopia, France, Haiti, Iran, Iraq, Italy,
Kenya, Laos, Lebanon, Libya, Mali, Monaco, Mozambique, Myanmar (Burma), Namibia,
Nicaragua, Niger, North Korea, People’s Republic of China, Poland, Russia,
Singapore, Somalia, South Sudan, Sudan, Switzerland, Syria, Taiwan, Thailand,
Ukraine, United Arab Emirates, United Kingdom, Venezuela, Yemen, and Zimbabwe,
**as well as any jurisdiction subject to comprehensive U.S. country-wide,
territory-wide, or regional economic sanctions**.
Failure to comply may result in enforcement actions, including **revocation of
API access**. Builders should review [Kalshi’s Member
Agreement](https://kalshi.com/docs/kalshi-member-agreement.pdf) and ensure all
required geographic and regulatory restrictions are enforced before enabling
prediction market trading.
## Code Recipes
* [Discover prediction markets](/build/recipes/prediction-markets/discover-markets).
* [Track user positions](/build/recipes/prediction-markets/track-positions).
* [Monitor market lifecycle](/build/recipes/prediction-markets/monitor-market-lifecycle).
* [Redeem outcome tokens](/build/recipes/prediction-markets/redeem-outcome-tokens).
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Identity Verification with Proof (KYC)
Source: https://pond.dflow.net/learn/proof
How identity verification works with Proof
## What Proof Is
Proof is an identity verification service that builds a proprietary identity graph linking verified real-world identities to Solana wallets. It enables partner applications to verify that a wallet belongs to a KYC'd individual without handling identity verification themselves.
Users verify once and can use their verified identity across all partner applications that integrate with Proof.
## When Proof Is Required
Buying prediction market outcome tokens requires Proof verification. Spot trading does not require Proof. See [Understanding KYC for Prediction Markets](/build/prediction-markets/kyc) for details.
## Why You Should Care
Many applications require identity verification for regulatory compliance, but building and maintaining KYC infrastructure is complex and expensive. Proof solves this by:
* **Reducing friction**: Apps can outsource identity verification while maintaining a seamless user experience.
* **Ensuring compliance**: Partner applications can meet regulatory requirements by verifying wallet ownership through Proof's identity graph.
* **Enabling portability**: Users complete verification once and reuse it across all integrated applications.
For builders, this means you can focus on your core product while Proof handles the identity layer.
## What Information Gets Verified
Proof verifies the following information about users:
| Verified Information |
| ------------------------- |
| Name |
| Address |
| Contact Information |
| Government Identification |
## How Verification Works
Identity verification in Proof follows a straightforward process:
1. **Authentication**: Users authenticate with their email using one-time codes.
2. **Document verification**: Users submit a government-issued ID for verification.
3. **Biometric verification**: Users complete a selfie matching check (liveness check).
4. **Status communication**: Users see clear status updates (pending, verified, failed).
Once verified, the user's identity is stored in Proof's identity graph and linked to their authenticated session.
## How Wallet Linking Works
After verification, users can link one or more Solana wallets to their verified identity:
1. User initiates wallet linking in Proof.
2. User signs a message with their wallet to prove ownership.
3. Proof verifies the signature cryptographically.
4. The wallet is linked to the user's verified identity.
From a builder's perspective, this creates a queryable mapping between wallets and verified identities that you can check via the Proof API.
Users can link multiple wallets to a single verified identity and manage them over time—adding labels, removing wallets, or linking new ones.
## How Partner Integration Works
Partners can integrate with Proof in two ways:
**Deep linking**: Redirect users to Proof with a wallet address and pre-signed ownership proof. After verification, users are redirected back to your app.
**Verification API**: Query the Proof API to check if a wallet is linked to a verified identity. This lets you gate features or actions based on verification status.
## What Builders Can Build
* Onboarding flows that require identity verification.
* Gated features for verified users only.
* Compliance-aware trading or financial applications.
* Apps that need to verify wallet ownership without building KYC infrastructure.
* Multi-app ecosystems where users verify once and access multiple services.
## Build With Proof
* [Introduction to Proof](/build/proof/introduction)
* [User journeys](/build/proof/user-journeys)
* [Partner integration](/build/proof/partner-integration)
* [Proof API reference](/build/proof-api/introduction)
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Trading Different Asset Types
Source: https://pond.dflow.net/learn/trading-different-asset-types
How to trade different asset types with DFlow
DFlow uses the same trading model for all asset types. What changes is **what is being traded**, not **how trading works**.
### Trading Crypto
When trading crypto, users swap one SPL token for another.
* A quote is requested.
* The user signs and submits a transaction.
* The trade routes through available [onchain liquidity venues](/learn/onchain-liquidity-venues).
* The output token is available in the user’s wallet.
This applies to spot assets like SOL, stablecoins, and other SPL tokens, enabling builders to ship familiar swap experiences, trading UIs, and automated strategies without building execution logic from scratch.
### Trading Prediction Markets
When trading prediction markets, users trade **outcome tokens** that represent possible results of an event.
* A quote is requested for an outcome token.
* The user signs and submits a transaction.
* The trade executes through [Kalshi’s](https://kalshi.com) prediction market liquidity.
* The outcome token is available in the user’s wallet.
All prediction market trades on DFlow execute through **[Concurrent Liquidity Programs (CLPs)](/learn/clp)** and use multi-transaction async execution.
Outcome tokens can be traded again or redeemed after the market resolves, opening up new possibilities for builders such as secondary trading, portfolio tracking, automated strategies, and post-resolution settlement flows.
### How These Trades Are the Same
From a trading perspective, crypto and prediction market trades follow the same flow:
* Quotes are requested the same way.
* Users sign and submit transactions the same way.
* The same routing and execution primitives apply.
DFlow treats both as first-class trading flows.
### Where They Differ
The differences come from **asset behavior and liquidity structure**, not from the trading model itself.
* Crypto trades usually complete atomically.
* Prediction market trades always execute asynchronously through [CLPs](/learn/clp).
* Prediction markets eventually resolve, allowing outcome tokens to be redeemed.
Despite these differences, developers interact with both through the same APIs.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# What is DFlow
Source: https://pond.dflow.net/learn/what-is-dflow
Overview of DFlow's trading infrastructure on Solana
DFlow is the most powerful trading infrastructure on Solana, enabling apps to access the cutting edge of financial markets.
Across both spot token trading and prediction markets, DFlow serves millions of users globally and is trusted by the largest trading platforms.
As execution adapts to onchain market conditions at the moment a trade executes:
* **Users** benefit from better realized prices and fewer failed trades.
* **Builders** benefit from a single API allowing them to trade multiple classes of assets.
## What DFlow Provides
Plug into tens of billions in monthly routed volume and liquidity across
every major DEX and high-frequency Prop AMM.
Execute trades with [Just-In-Time (JIT) routing](/learn/jit-routing) that follows the best
available onchain price at execution time.
[Trade any token](/learn/trading-different-asset-types) with smart order routing, best price, and near-complete
token coverage on Solana.
Trade [spot assets](/learn/declarative-trades) and [prediction market outcomes](/learn/prediction-markets) through the same execution
model.
Execute trades using [custom swap routing](/learn/imperative-trades), giving apps explicit control over
routing and execution.
Trade against offchain liquidity providers using [Concurrent Liquidity
Programs (CLPs)](/learn/clp), where users write limit orders onchain and fills land in a
separate transaction.
Need Help?
Connect with other developers, get help, and stay updated on the latest
DFlow developments.
Join the DFlow Dev Notifications Telegram group to stay in the loop on
new features and other announcements.
# Prediction Market Compliance
Source: https://pond.dflow.net/legal/prediction-market-compliance
Regulatory and compliance requirements for Kalshi markets
Prediction market trading through Kalshi is subject to U.S. regulatory
requirements.
Builders integrating tokenized Kalshi markets are responsible for ensuring
their applications comply with Kalshi’s member obligations. This includes
enforcing **geo-blocking for users in the United States and other restricted
jurisdictions**. Kalshi operates as a CFTC-regulated exchange, and access to
its markets is prohibited from certain countries and regions.
Access must be blocked from the **United States** and the following
jurisdictions:
Afghanistan, Algeria, Angola, Australia, Belarus, Belgium, Bolivia, Bulgaria,
Burkina Faso, Cameroon, Canada, Central African Republic, Côte d’Ivoire, Cuba,
Democratic Republic of the Congo, Ethiopia, France, Haiti, Iran, Iraq, Italy,
Kenya, Laos, Lebanon, Libya, Mali, Monaco, Mozambique, Myanmar (Burma), Namibia,
Nicaragua, Niger, North Korea, People’s Republic of China, Poland, Russia,
Singapore, Somalia, South Sudan, Sudan, Switzerland, Syria, Taiwan, Thailand,
Ukraine, United Arab Emirates, United Kingdom, Venezuela, Yemen, and Zimbabwe,
**as well as any jurisdiction subject to comprehensive U.S. country-wide,
territory-wide, or regional economic sanctions**.
Failure to comply may result in enforcement actions, including **revocation of
API access**. Builders should review [Kalshi’s Member
Agreement](https://kalshi.com/docs/kalshi-member-agreement.pdf) and ensure all
required geographic and regulatory restrictions are enforced before enabling
prediction market trading.
# Privacy Policy
Source: https://pond.dflow.net/privacy
Effective as of August 29, 2024
This Privacy Policy describes how DFlow Inc. ("DFlow," "we", “us” or "our") handles personal information that we collect through our digital properties that link to this Privacy Policy, including our website, mobile application, as well as through social media, our marketing activities, and other activities described in this Privacy Policy (collectively, the “Service”).
## Personal Information We Collect
Information you provide to us. Personal information you may provide to us through the Service or otherwise includes:
• Contact data, such as your first and last name, email address, professional title, and phone number.
• Profile data, such as the username and password that you may set to establish an online account on the Service, crypto wallet address, and any other information that you add to your account profile.
• Communications that we exchange with you, including when you contact us through the Service, social media, or otherwise.
• Transactional data, such as information relating to or needed to complete your orders on or through the Service, including order flow bids, sales offers and purchase history.
• Blockchain data, such as crypto wallet accounts and associated details.
• Financial data, such as your virtual currency or wallet accounts, stored value accounts, and associated details.
• Investment data, such as royalties, fees, sales prices, and digital asset data.
• Marketing data, such as your preferences for receiving our marketing communications and any information you provide when you engage with them.
• Other data not specifically listed here, which we will use as described in this Privacy Policy or as otherwise disclosed at the time of collection.
THIRD-PARTY SOURCES. We may combine personal information we receive from you with personal information we obtain from other sources, such as:
• Public sources, such as public blockchains such as Solana, social media platforms, and other publicly available sources.
• Data providers, such as information services and data licensors that provide demographic and other information.
• Marketing partners, such as joint marketing partners.
• Third-party services, such as web3 authentication services, that you use to log into, or otherwise link to, your Service account. This data may include your wallet address and other information associated with your account on that third-party service that is made available to us based on your account settings on that service.
AUTOMATIC DATA COLLECTION. We, our service providers, and our business partners may automatically log information about you, your computer or mobile device, and your interaction over time with the Service, our communications and other online services, such as:
• Device data, such as your computer’s or mobile device’s operating system type and version, manufacturer and model, browser type, screen resolution, RAM and disk size, CPU usage, device type (e.g., phone, tablet), IP address, unique identifiers (including identifiers used for advertising purposes), language settings, mobile device carrier, radio/network information (e.g., Wi-Fi, LTE, 3G), and general location information such as city, state or geographic area.
• Online activity data, such as pages or screens you viewed, how long you spent on a page or screen, the website you visited before browsing to the Service, navigation paths between pages or screens, information about your activity on a page or screen, access times and duration of access, and whether you have opened our emails or clicked links within them.
• Location data when you authorize the Service to access your device’s location.
o Communication interaction data, such as your interactions with our email, text or other communications (e.g., whether you open and/or forward emails) – we may do this through use of pixel tags (which are also known as clear GIFs), which may be embedded invisibly in our emails.
COOKIES AND OTHER TECHNOLOGIES. Some of the automatic collection described above is facilitated by the following technologies:
• Cookies, which are small text files that websites store on user devices and that allow web servers to record users’ web browsing activities and remember their submissions, preferences, and login status as they navigate a site. Cookies used on our sites include both “session cookies” that are deleted when a session ends, “persistent cookies” that remain longer, “first party” cookies that we place and “third party” cookies that our third-party business partners and service providers’ place.
• Local storage technologies, like HTML5, that provide cookie-equivalent functionality but can store larger amounts of data on your device outside of your browser in connection with specific applications.
• Web beacons, also known as pixel tags or clear GIFs, which are used to demonstrate that a webpage or email address was accessed or opened, or that certain content was viewed or clicked.
• Software development kits, or SDK, is third-party computer code that we may incorporate into our mobile applications that may be used for a variety of purposes, including to provide us with analytics regarding the use of our mobile applications, to integrate with social media, or add features or functionality to our app.
• Chat technologies, such as those provided by Intercom that to operate the chat features that you can use to communicate with us through the Service. Intercom and other third parties may access and use information about webpages visited on our website, your IP address, your general geographic information (e.g., city, state), and other personal information you share through online chats for the purposes described in this Privacy Policy. You can learn more about Intercom at [https://www.intercom.com/legal/privacy](https://www.intercom.com/legal/privacy).
## How We Use Your Personal Information
We may use your personal information for the following purposes or as otherwise described at the time of collection:
SERVICE DELIVERY. We may use your personal information to:
• provide, operate and improve the Service and our business;
• establish and maintain your user profile on the Service;
• personalizing the service, including remembering the devices from which you have previously logged in and remembering your selections and preferences as you navigate the Service;
• communicate with you about the Service, including by sending announcements, updates, security alerts, and support and administrative messages;
• understand your needs and interests, and personalize your experience with the Service and our communications; and
• provide support for the Service, and respond to your requests, questions and feedback.
RESEARCH AND DEVELOPMENT. We may use your personal information for research and development purposes, including to analyze and improve the Service and our business. As part of these activities, we may create aggregated, de-identified or other anonymous data from personal information we collect. We make personal information into anonymous data by removing information that makes the data personally identifiable to you. We may use this anonymous data and share it with third parties for our lawful business purposes, including to analyze and improve the Service and promote our business.
MARKETING AND ADVERTISING. We and our service providers and our third-party advertising partners may collect and use your personal information for direct marketing purposes.
• Direct marketing. We may send you DFlow-related marketing communications about our products, services or promotions that may be of interest to you. You may opt-out of our marketing communications as described in the Opt-out of marketing section below.
• Interest-based advertising. We and our third-party advertising partners may use cookies and similar technologies to collect information about your interaction with the Service, our communications and other online services over time, and use that information to serve online ads that they think will interest you. This is called interest-based advertising. We may also share information about our users with these companies to facilitate interest-based advertising to those or similar users on other online platforms.
SERVICE IMPROVEMENT AND ANALYTICS. We may use your personal information to analyze your usage of the Service, improve the Service, improve the rest of our business, help us understand user activity on the Service, including which pages are most and least visited and how visitors move around the Service, as well as user interactions with our emails, and to develop new products and services.
COMPLIANCE AND PROTECTION. We may use your personal information to:
• comply with applicable laws, lawful requests, and legal process, such as to respond to subpoenas or requests from government authorities;
• protect our, your or others’ rights, privacy, safety or property (including by making and defending legal claims);
• audit our internal processes for compliance with legal and contractual requirements or our internal policies;
• enforce the terms and conditions that govern the Service; and
• prevent, identify, investigate and deter fraudulent, harmful, unauthorized, unethical or illegal activity, including cyberattacks and identity theft.
WITH YOUR CONSENT. In some cases, we may specifically ask for your consent to collect, use or share your personal information, such as when required by law.
COOKIES AND OTHER TECHNOLOGIES. In addition to the other uses included in this section, we may use the Cookies and other technologies described above for the following purposes:
• Technical operation. To allow the technical operation of the Service, such as by remembering your selections and preferences as you navigate the site.
• Functionality. To enhance the performance and functionality of our services.
• Advertising. To help our third-party advertising partners collect information about how you use the Service and other online services over time, which they use to show you ads on other online services they believe will interest you and measure how the ads perform.
• Analytics. To help us understand user activity on the Service, including which pages are most and least visited and how visitors move around the Service, as well as user interactions with our emails. For example, we use Google Analytics for this purpose. You can learn more about Google Analytics and how to prevent the use of Google Analytics relating to your use of our sites here: [https://tools.google.com/dlpage/gaoptout?hl=en](https://tools.google.com/dlpage/gaoptout?hl=en).
RETENTION. We generally retain personal information to fulfill the purposes for which we collected it, including for the purposes of satisfying any legal, accounting, or reporting requirements, to establish or defend legal claims, or for fraud prevention purposes. To determine the appropriate retention period for personal information, we may consider factors such as the amount, nature, and sensitivity of the personal information, the potential risk of harm from unauthorized use or disclosure of your personal information, the purposes for which we process your personal information and whether we can achieve those purposes through other means, and the applicable legal requirements.
## How We Share Your Personal Information
We may share your personal information with the following parties and as otherwise described in this Privacy Policy or at the time of collection.
AFFILIATES. Our corporate parent, subsidiaries, and affiliates, for purposes consistent with this Privacy Policy.
SERVICE PROVIDERS. Third parties that provide services on our behalf or help us operate the Service or our business (such as hosting, information technology, online chat functionality providers, customer support, email delivery, marketing, consumer research and website analytics).
THIRD PARTIES DESIGNATED BY YOU. We may share your personal information with third parties where you have instructed us or provided your consent to do so.
CRYPTOCURRENCY PLATFORMS. Any information collected necessary to process a digital asset order (such as your wallet address) is collected and processed directly by your chosen cryptocurrency platform. Please review the privacy policies for the relevant cryptocurrency platform to learn how they may use your payment information.
LINKED THIRD-PARTY SERVICES. If you log into the Service with, or otherwise link your Service account to, a third-party service such as Dynamic, we may share your personal information with that third-party service. The third party’s use of the shared information will be governed by its privacy policy and the settings associated with your account with the third-party service. To learn more about how Dynamic handles your personal information, please refer to their privacy policy located at [https://www.dynamic.xyz/privacy-policy](https://www.dynamic.xyz/privacy-policy).
ADVERTISING PARTNERS. Third-party advertising companies for the interest-based advertising purposes described above.
BUSINESS AND MARKETING PARTNERS. Third parties with whom we co-sponsor events or promotions, with whom we jointly offer products or services, or whose products or services may be of interest to you.
PROFESSIONAL ADVISORS. Professional advisors, such as lawyers, auditors, bankers and insurers, where necessary in the course of the professional services that they render to us.
AUTHORITIES AND OTHERS. Law enforcement, government authorities, and private parties, as we believe in good faith to be necessary or appropriate for the compliance and protection purposes described above.
BUSINESS TRANSFEREES. Acquirers and other relevant participants in business transactions (or negotiations of or due diligence for such transactions) involving a corporate divestiture, merger, consolidation, acquisition, reorganization, sale or other disposition of all or any portion of the business or assets of, or equity interests in, DFlow or our affiliates (including, in connection with a bankruptcy or similar proceedings).
## Your Choices
ACCESS OR UPDATE YOUR INFORMATION. If you have registered for an account with us through the Service, you may review and update certain account information by logging into the account.
OPT-OUT OF MARKETING COMMUNICATIONS. You may opt-out of marketing-related emails by following the opt-out or unsubscribe instructions at the bottom of the email, or by contacting us. Please note that if you choose to opt-out of marketing-related emails, you may continue to receive service-related and other non-marketing emails.
COOKIES. Most browsers let you remove or reject cookies. To do this, follow the instructions in your browser settings. Many browsers accept cookies by default until you change your settings. Please note that if you set your browser to disable cookies, the Service may not work properly. For more information about cookies, including how to see what cookies have been set on your browser and how to manage and delete them, visit [www.allaboutcookies.org](http://www.allaboutcookies.org).
DO NOT TRACK. Some Internet browsers may be configured to send “Do Not Track” signals to the online services that you visit. We currently do not respond to “Do Not Track.” To find out more about “Do Not Track,” please visit [http://www.allaboutdnt.com](http://www.allaboutdnt.com).
DECLINING TO PROVIDE INFORMATION. We need to collect personal information to provide certain services. If you do not provide the information we identify as required or mandatory, we may not be able to provide those services.
DELETE YOUR CONTENT OR CLOSE YOUR ACCOUNT. You can choose to delete certain content through your account. If you wish to request to close your account, please contact us.
ADVERTISING CHOICES. You may be able to limit use of your information for interest-based advertising through the following settings/options/tools:
• Browser settings. Changing your internet web browser settings to block third-party cookies.
• Privacy browsers/plug-ins. Using privacy browsers and/or ad-blocking browser plug-ins that let you block tracking technologies.
• Platform settings. Certain platforms offer opt-out features that let you opt-out of use of your information for interest-based advertising. For example, you may be able to exercise that option for Google and Facebook, respectively, at the following websites:
o Google: [https://adssettings.google.com/](https://adssettings.google.com/)
o Facebook: [https://www.facebook.com/about/ads](https://www.facebook.com/about/ads)
• Ad industry tools. Opting out of interest-based ads from companies that participate in the following industry opt-out programs:
o Network Advertising Initiative: [http://www.networkadvertising.org/managing/opt\_out.asp](http://www.networkadvertising.org/managing/opt_out.asp)
o Digital Advertising Alliance: optout.aboutads.info.
o AppChoices mobile app, available at [https://www.youradchoices.com/appchoices](https://www.youradchoices.com/appchoices), which will allow you to opt-out of interest-based ads in mobile apps served by participating members of the Digital Advertising Alliance.
You will need to apply these opt-out settings on each device and browser from which you wish to limit the use of your information for interest-based advertising purposes. We cannot offer any assurances as to whether the companies we work with participate in the opt-out programs described above.
OTHER SITES AND SERVICES
The Service may contain links to websites, mobile applications, and other online services operated by third parties. In addition, our content may be integrated into web pages or other online services that are not associated with us. These links and integrations are not an endorsement of, or representation that we are affiliated with, any third party. We do not control websites, mobile applications or online services operated by third parties, and we are not responsible for their actions. We encourage you to read the privacy policies of the other websites, mobile applications and online services you use.
SECURITY
We employ technical, organizational and physical safeguards designed to protect the personal information we collect. However, security risk is inherent in all internet and information technologies, and we cannot guarantee the security of your personal information.
INTERNATIONAL DATA TRANSFER
We are headquartered in the United States and may use service providers that operate in other countries. Your personal information may be transferred to the United States or other locations where privacy laws may not be as protective as those in your state, province, or country.
CHILDREN
The Service is not intended for use by anyone under 18 years of age. If you are a parent or guardian of a child from whom you believe we have collected personal information in a manner prohibited by law, please contact us. If we learn that we have collected personal information through the Service from a child without the consent of the child’s parent or guardian as required by law, we will comply with applicable legal requirements to delete the information.
CHANGES TO THIS PRIVACY POLICY
We reserve the right to modify this Privacy Policy at any time. If we make material changes to this Privacy Policy, we will notify you by updating the date of this Privacy Policy and posting it on the Service or other appropriate means. Any modifications to this Privacy Policy will be effective upon our posting the modified version (or as otherwise indicated at the time of posting). In all cases, your use of the Service after the effective date of any modified Privacy Policy indicates your acceptance of the modified Privacy Policy.
## How to Contact Us
Email: [hello@dflow.net](mailto:hello@dflow.net)
# Terms of Service
Source: https://pond.dflow.net/terms-of-service
DFlow
Terms Of Service
Last Updated: May 21, 2024
1. INTRODUCTION
These Terms of Service (these “Terms”) govern your access to and use of: certain products, services and properties made available by DFlow Inc. (“DFlow,” “we,” “us” or “our”), including the website, available at [https://dflow.net/](https://dflow.net/) (the “Website”); our progressive web application (the “Web App”) and any mobile application (“Application”) that we offer subject to these Terms, the DFlow Platform (as defined below), governed by the DFlow Protocol (as defined below), which enables Trading Entities (as defined below) to bid on and purchase the right to receive orders (“Orders”) to buy, sell and trade Digital Assets, both on an individual and a batch basis (collectively, “Order Flow”), from third-party wallets (“Order Flow Wallets”); and any software and services provided on or in connection with the Website, Web App, Application, Platform, and DFlow Protocol (collectively with the Website, Web App, Application, and Platform, “Service(s)”). As used herein, the terms “you,” and “your” refer to each individual who enters into these Terms on such individual’s own behalf or any entity on behalf of which an individual enters into these Terms. Certain features of the Service may be subject to additional guidelines, terms, or rules (“Supplemental Terms”), which will be displayed in connection with such features. All such Supplemental Terms are incorporated by reference into these Terms. If these Terms are inconsistent with any Supplemental Terms, the Supplemental Terms shall control solely with respect to such services.
THESE TERMS OF USE ARE IMPORTANT AND AFFECT YOUR LEGAL RIGHTS, SO PLEASE READ THEM CAREFULLY. BY BROWSING THE WEBSITE, DOWNLOADING THE WEB APP OR ANY APPLICATION, CONNECTING A DIGITAL WALLET TO THE SERVICE, ACCESSING OR USING THE DFLOW PROTOCOL THROUGH THE SERVICE, AND/OR OTHERWISE USING THE SERVICE, YOU AGREE TO BE BOUND BY THESE TERMS AND ALL OF THE TERMS INCORPORATED HEREIN BY REFERENCE. IF YOU DO NOT AGREE TO THESE TERMS, YOU MAY NOT ACCESS OR USE THE SERVICE.
THE SERVICE PROVIDES A USER INTERFACE THAT ENABLES END USERS TO INTERACT WITH THE DFLOW PROTOCOL. WE ARE NOT A LICENSED EXCHANGE, FUNDING PORTAL, CUSTODIAN, TRUST COMPANY, LICENSED BROKER, DEALER, BROKER-DEALER, INVESTMENT ADVISOR, INVESTMENT MANAGER, FINANCIAL ADVISER, FINANCIAL INSTITUTION, LENDER, OR BORROWER, WHETHER IN THE UNITED STATES OR ELSEWHERE. THE SERVICE IS AN ADMINISTRATIVE PLATFORM ONLY. NEITHER DFLOW NOR OUR SERVICE GIVES, OFFERS OR RENDERS INVESTMENT, TAX, OR LEGAL ADVICE. THE SERVICE INCLUDES A SOFTWARE-BASED PLATFORM THAT ALLOWS ORDER FLOW WALLETS, CENTRALIZED AND DECENTRALIZED TRADING ENTITIES (“TRADING ENTITIES”), AND OTHER PARTIES TO BUY AND SELL DIGITAL ASSET ORDER FLOW TO AND FROM THIRD PARTIES UNAFFILIATED WITH DFLOW. BEFORE MAKING FINANCIAL OR INVESTMENT DECISIONS, WE RECOMMEND THAT YOU CONTACT AN INVESTMENT ADVISOR, OR TAX OR LEGAL PROFESSIONAL. DFLOW IS NOT A PARTY TO ANY AGREEMENT BETWEEN ANY USERS OF THE SERVICE. YOU SPECIFICALLY ACKNOWLEDGE AND AGREE THAT DFLOW SHALL NOT BE A PARTY TO OR HAVE ANY RESPONSIBILITY OR LIABILITY FOR, ARISING OUT OF, RELATING TO, ASSOCIATED WITH OR RESULTING FROM ANY DISPUTES BETWEEN YOU AND ANY BUYER OR SELLER OF ORDER FLOW IN RESPECT OF THE USE, MISUSE, PROVISION OR FAILURE TO PROVIDE ANY USER ASSET (AS DEFINED BELOW).
YOU BEAR FULL RESPONSIBILITY FOR VERIFYING THE IDENTITY, LEGITIMACY, AND AUTHENTICITY OF ANY SOFTWARE PLATFORM YOU TRANSACT WITH THROUGH THE SERVICE. DFLOW MAKES NO CLAIMS ABOUT THE IDENTITY, LEGITIMACY, OR AUTHENTICITY OF ANY SOFTWARE PLATFORM, INCLUDING ANY DEFI PLATFORM (AS DEFINED BELOW).
PLEASE BE AWARE THAT SECTION 16 CONTAINS PROVISIONS GOVERNING HOW TO RESOLVE DISPUTES BETWEEN YOU AND DFLOW. AMONG OTHER THINGS, SECTION 16 INCLUDES AN AGREEMENT TO ARBITRATE WHICH REQUIRES, WITH LIMITED EXCEPTIONS, THAT ALL DISPUTES BETWEEN YOU AND US SHALL BE RESOLVED BY BINDING AND FINAL ARBITRATION. SECTION 16 ALSO CONTAINS A CLASS ACTION AND JURY TRIAL WAIVER. PLEASE READ SECTION 16 CAREFULLY.
UNLESS YOU OPT OUT OF THE AGREEMENT TO ARBITRATE WITHIN 30 DAYS: (1) YOU WILL ONLY BE PERMITTED TO PURSUE DISPUTES OR CLAIMS AND SEEK RELIEF AGAINST US ON AN INDIVIDUAL BASIS, NOT AS A PLAINTIFF OR CLASS MEMBER IN ANY CLASS OR REPRESENTATIVE ACTION OR PROCEEDING AND YOU WAIVE YOUR RIGHT TO PARTICIPATE IN A CLASS ACTION LAWSUIT OR CLASS-WIDE ARBITRATION; AND (2) YOU ARE WAIVING YOUR RIGHT TO PURSUE DISPUTES OR CLAIMS AND SEEK RELIEF IN A COURT OF LAW AND TO HAVE A JURY TRIAL.
PLEASE BE AWARE THAT SECTION 6.c OF THESE TERMS, BELOW, CONTAINS YOUR OPT-IN CONSENT TO RECEIVE COMMUNICATIONS FROM US, INCLUDING EMAIL COMMUNICATIONS.
Please refer to our Privacy Policy for information about how we collect, use and share personal information about you. By submitting data through the Service, you expressly consent to the collection, use and disclosure of your personal data in accordance with the Privacy Policy.
DFlow reserves the right to change or modify these Terms at any time and in our sole discretion. If we make changes to these Terms, we will provide notice of such changes, such as by sending an email notification, providing notice through the Service or updating the “Last Updated” date at the beginning of these Terms. By continuing to access or use the Service at any point after such update, you confirm your acceptance of the revised Terms and all of the terms incorporated therein by reference. We encourage you to review these Terms frequently to ensure that you understand the terms and conditions that apply when you access or use the Service. If you do not agree to the revised Terms, you may not access or use the Service.
2. THE DFLOW PROTOCOL
a. Use of the DFlow Protocol. The DFlow Protocol governs the DFlow application-specific blockchain platform (“Platform”), a digital network that supports smart contracts and enables users to deploy cryptocurrency and other digital assets (“Digital Assets”) across one or more third party digital platforms, including any blockchain networks or networks of smart contracts (“DeFi Platforms”) which support Digital Asset trading (the “DFlow Protocol”). DFlow may not have actual or constructive administrative control over the DFlow Protocol or your use thereof, and may not be able to access, transfer, or take custody of Digital Assets stored in, transferred via, or custodied by any smart contract enabled by the DFlow Protocol, nor may DFlow have the ability to upgrade or modify any existing smart contracts that are part of the DFlow Protocol. DFlow does not necessarily monitor or control any use of the DFlow Protocol by third parties and/or any use of the DFlow Protocol that does not take place on or through the Services. DFlow makes no representations or warranties about the functionality of the DFlow Protocol. All use of the DFlow Protocol is undertaken at your own risk, and DFlow is not and shall not be liable to you or to any third party for any loss or damage arising from or connected to your or any third party’s use of the DFlow Protocol. Notwithstanding anything to the contrary set forth herein, the terms of Section 12 (Assumption of Risk Related to Blockchain Technology), Section 14 (Disclaimers), and Section 15 (Limitation of Liability) of the Terms apply, mutatis mutandis, to any claims arising out of your use of the DFlow Protocol.
b. No Updates or Modifications. DFlow does not have the ability to freeze the DFlow Protocol, nor does DFlow have the ability to update previously released smart contracts or transactions that are part of the DFlow Protocol. DFlow may, at its sole discretion, choose to release a new version of the DFlow Protocol. The Service may not be interoperable with prior, abandoned, or outdated versions of the DFlow Protocol.
3. OUR SERVICE
a. The Service. In order to access certain Services, you may be required to become a “Registered User” by connecting a software-based digital wallet (a “Digital Wallet”) to the Service (which shall include any noncustodial Digital Wallet created by you through the Service (a “DFlow Wallet”)). If you create a DFlow Wallet, you may connect to that DFlow Wallet through a phone number, email address, or other third-party account (“Linked Account”). A Registered User can visualize such Registered User’s Digital Assets, Order Flow bids (“Bids”), Order Flow sales offers (“Sale Offers”), or previously executed Order Flow sales or purchases (“User Assets”) that have been deployed across DeFi Platforms using the DFlow Protocol (each such deployment, a “Transaction”). These visualizations may include graphs, projections, and other information about your User Assets (collectively, “User Asset Information”), including without limitation any amounts earned by you from the sale of User Assets through DeFi Platforms using the DFlow Protocol (“Earnings”). DFlow does not own or control your Digital Wallet, DFlow Wallet or any Defi Platform.
b. DFlow Protocol. DFlow does not have any access to or control over your User Assets when you deploy such User Assets using the DFlow Protocol, and all use of the DFlow Protocol is at your own risk. Information that may be provided to you by the Service about your allocation of your User Assets and your Earnings are all considered User Asset Information.
c. Your User Assets. When you use the Service, you represent and warrant that (a) you own or have the authority to connect to the Digital Wallet; (b) you own or have the authority to deploy any User Assets; (c) all User Assets you deploy or otherwise make available in connection with the Service have been earned, received, or otherwise acquired by you in compliance with all applicable laws; and (d) no User Assets that you deploy or otherwise make available in connection with the Service or the DFlow Protocol have been “tumbled” or otherwise undergone any process designed to hide, mask, or obscure the origin or ownership of such User Assets.
d. DFlow Wallets. DFlow Wallets are noncustodial Digital Wallets owned and controlled by you. DFlow does not have actual or constructive access to any DFlow Wallet, and you, and not DFlow, are solely responsible for the protection and maintenance of your DFlow Wallet and any User Assets therein, including without limitation for protecting the security of and maintaining access to any Linked Account that you use to access your DFlow Wallet. You acknowledge and agree that DFlow shall have no obligation to you in connection with your use of or inability to use or access your DFlow Wallet.
e. Compatibility Risk. The Service may not be compatible with all forms of cryptocurrency, and certain of your User Assets may not be compatible with the Service. Whether or not a User Asset is then-currently compatible with the Service may change at any time, in DFlow’s sole discretion, with or without notice to you.
f. Earnings. Any Earnings that you receive in connection with your use of the DFlow Protocol are provided by the applicable Defi Platform or Trading Entities, and not DFlow. Any Earnings you receive or do not receive are at the sole discretion of such Defi Platform(s) or Trading Entities, and DFlow shall have no obligation to you to facilitate any Earnings payment and no liability to you in connection with any Earnings or your failure to receive the same. DFlow does not custody or control your User Assets, and does not provide, guarantee, or promise any return or Earnings on your User Assets.
g. Price Impacts. The deployment of your User Assets across the Services, including your deployment of Bids and Sale Offers prior to the execution of a Transaction, may impact the price on certain digital asset exchanges, now or in the future, of the Digital Asset underlying such User Assets, or other related Digital Assets. DFlow has no obligation to you, or to any third party, including the owner of a Digital Asset underlying such Bid or Sale offer, to mitigate such price impacts, and shall make no efforts to do so in its provision of the Services.
h. Taxes. You are solely responsible (and DFlow has no responsibility) for determining what, if any, taxes apply to any Transactions involving your User Assets, including your receipt of any Earnings.
i. Web App License. Subject to your compliance with this Agreement, DFlow grants you a limited non-exclusive, non-transferable, non-sublicensable, revocable license to download, install and use a copy of the Web App on a limited number of devices that you own or control and to run such copies of the Web App solely for your own personal or internal business purposes.
j. Application License. Subject to your compliance with this Agreement, DFlow grants you a limited non-exclusive, non-transferable, non-sublicensable, revocable license to download, install and use a copy of the Application on a single mobile device that you own or control and to run such copy of the Application solely for your own personal or internal business purposes.
k. Open Source Software. You acknowledge and agree that the Service may use, incorporate or link to certain software made available under an “open-source” or “free” license (“OSS”), and that your use of the Service is subject to, and you agree to comply with, any applicable OSS licenses. Each item of OSS is licensed under the terms of the end-user license that accompanies such OSS. Nothing in these Terms limits your rights under, or grants you rights that supersede, the terms and conditions of any applicable end user license for the OSS. If required by any license for particular OSS, DFlow makes such OSS, and DFlow’s modifications thereto, available by written request at the notice address specified below.
l. Updates. You understand that the Service is evolving. As a result, DFlow may require you to install updates to the Web App or Applications that you have installed on the devices through which you access or use the Service. You acknowledge and agree that DFlow may update the Service with or without notifying you. You may need to update third-party software from time to time in order to continue to use the Service. Any future release, update or other addition to the Service shall be subject to this Agreement.
4. API Usage.
a. Our API. DFlow may enable you to use an application programming interface for sending data to or receiving data from the Platform and any software libraries made available by us for accessing the foregoing (collectively, the “API”). The API, and any software, code, or other information received by you through the API (“Licensed Data”), and any documentation made available in connection therewith on the Service (“Documentation”) constitute part of our Service.
b. API Fee. In consideration for the API license set forth in this Section, you agree to pay DFlow the amounts set forth in connection with the API on the Service, which shall be a percentage of the amounts charged by you to your end users for use of such API and/or Licensed Data, as may be updated from time to time upon notice (“Fees”). Your ongoing use of the API following such update shall constitute your acceptance to the updated Fees. If you do not wish to accept any updated Fees, your sole remedy is to immediately stop using the API. Notwithstanding any fluctuation in the value of any currency, whether fiat or cryptocurrency, you shall pay all Fees in the currency in which you have agreed to pay such Fees. DFlow reserves the right to add any supported currencies or cryptocurrencies at any time, in DFlow’s sole discretion. DFlow may suspend your access to the Platform and API immediately upon notice to you if you fail to pay any amounts hereunder. DFlow shall be entitled to withhold performance and discontinue service until all unpaid amounts due are paid in full. Amounts due to DFlow are exclusive of all applicable sales, use, value-added, and other taxes, and all applicable duties, tariffs, assessments, export and import fees, or other similar charges, and you will be responsible for payment of all such taxes (other than taxes based on DFlow’s revenue or income), fees, duties, and charges and any related penalties and interest, arising from the payment of Fees due hereunder, or your use of the API. You agree that you will make all payments of amounts due to DFlow free and clear of, and without reduction for, any withholding taxes; any such taxes imposed on payments of amounts due to DFlow will be your sole responsibility, and You shall indemnify and hold harmless DFlow in connection with any proceedings brought by any taxing authorities arising from your failure to pay any taxes for which you are responsible hereunder.
c. License to API. Subject to your ongoing compliance with the terms of this Agreement, DFlow hereby grants you a non-exclusive, non-transferable, non-sublicensable license, solely during the Term (as defined below) and solely for your internal business purposes, to: (a) use the API to submit data to and obtain data and other information from the Platform in accordance with any associated Documentation; (b) use the Licensed Data obtained in accordance with the foregoing (a); and (c) use and reproduce a reasonable number of copies of the Documentation solely as necessary to support your use of the API.
d. Disclaimers. You acknowledge and agree that the Licensed Data is output that enables your end users to more easily write transactions to DeFi Platforms, and that the API does not process any transactions or otherwise facilitate the flow of funds as a service to you or any third party. The API and Licensed Data are made available “as is” and “with all faults”, and you agree that you use the API and Licensed Data at your own risk.
e. Flow-Through Terms. If you make the API available to end users, you agree that your contract with such end users will reflect the restrictions and disclaimers set forth herein, and you agree to defend, indemnify, and hold DFlow harmless from and against any claims, losses, or damages arising from or related to your use of the API or Licensed Data, including without limitation any claims from or related to your end users.
5. Your Assumption of Risk.
a. WHEN YOU USE THE SERVICE, YOU UNDERSTAND AND ACKNOWLEDGE THAT DFLOW IS NOT A FINANCIAL OR INVESTMENT ADVISOR AND THAT THE SERVICE ENTAILS A RISK OF LOSS AND MAY NOT MEET YOUR NEEDS. DFlow may not be able foresee or anticipate technical or other difficulties which may result in data loss or other service interruptions. DFlow encourages you to periodically confirm the valuation and status of your User Assets through independent sources. DFlow is not responsible for your User Assets, and does not and cannot make any guarantee that your User Assets will earn any Earnings or that your User Assets will not lose value. The prices of cryptocurrency assets can be extremely volatile. DFlow makes no warranties as to the markets in which your User Assets are transferred, purchased, or traded.
b. You understand that the Service may not be suitable for your purposes, could have errors and, like any other software, the Service could be at risk of third-party malware, hacks or cybersecurity breaches. You agree that it is your responsibility to monitor your User Assets regularly and confirm their proper use and deployment consistent with your intentions.
c. In order to be successfully completed, any Transaction involving your User Assets initiated by or sent to your Digital Wallet must be confirmed by and recorded on the blockchain(s) supporting such User Assets. DFlow has no control over any third party blockchain and therefore cannot and does not ensure that any transaction details that you submit or receive via our Service will be validated by or confirmed on the relevant blockchain, and DFlow does not have the ability to facilitate any cancellation or modification requests. You accept and acknowledge that you take full responsibility for all activities that you effect through your Digital Wallet and accept all risks of loss, including loss as a result of any authorized or unauthorized access to your Digital Wallet, to the maximum extent permitted by law.
d. You represent and warrant that you (a) have the necessary technical expertise and ability to review and evaluate the security, integrity and operation of your Digital Wallet and any DeFi Platforms to which your User Assets may be deployed in connection with the Service; (b) have the knowledge, experience, understanding, professional advice and information to make your own evaluation of the merits, risks and applicable compliance requirements under applicable laws of any use of your Digital Wallet and any DeFi Platforms to which your User Assets may be deployed in connection with the Service; (c) know, understand and accept the risks associated with your Digital Wallet and any DeFi Platforms to which your User Assets may be deployed in connection with the Service; and (d) accept the risks associated with blockchain technology and DeFi Platforms generally, and are responsible for conducting your own independent analysis of the risks specific to your use of the Service. You further agree that DFlow will have no responsibility or liability for such risks.
e. You acknowledge and agree that:
● There are risks associated with using an Internet based currency, including but not limited to, the risk of hardware, software and Internet connections; the risk of malicious software introduction; the risk that third parties may obtain unauthorized access to information stored within your Digital Wallet; and the risk of counterfeit assets, mislabeled assets, assets that are vulnerable to metadata decay, assets on smart contracts with bugs, and assets that may become untransferable. You accept and acknowledge that DFlow will not be responsible for any communication failures, disruptions, errors, distortions or delays or losses you may experience when using blockchain technology, however caused.
● The regulatory regimes governing blockchain technologies, cryptocurrencies, and tokens are uncertain, and new regulations or policies may materially adversely affect the development of the Service.
● DFlow makes no guarantee as to the functionality of any blockchain’s decentralized governance, which could, among other things, lead to delays, conflicts of interest, or operational decisions that are unfavorable to your User Assets. You acknowledge and accept that the protocols governing the operation of a blockchain may be subject to sudden changes in operating rules which may materially alter the blockchain and affect the value and function of any of your User Assets supported by that blockchain.
● DFlow makes no guarantee as to the security of any blockchain or any DeFi Platform. DFlow is not liable for any hacks, double spending, stolen User Assets, or any other attacks on a blockchain or DeFi Platform.
● The DeFi Platforms are controlled by third parties, and DFlow is not responsible for their performance nor any risks associated with the use thereof. The Service relies on, and DFlow makes no guarantee or warranties as to the functionality of or access to, any DeFi Platform, Digital Wallet, or other Third-Party Service.
● You control your Digital Wallet, and DFlow is not responsible for its performance, nor any risks associated with the use thereof.
6. CONNECTING A DIGITAL WALLET; CONSENT TO ELECTRONIC COMMUNICATION
a. Connecting a Digital Wallet; Registration Information. In order to use certain features of the Service you will need to connect a compatible Digital Wallet and accept these Terms. You must be eighteen (18) years old to use the Service. When you connect your Digital Wallet to the Website or otherwise use the Service, you may be asked to provide certain information to us (“Registration Information”). You agree to (i) provide accurate, current, and complete Registration Information; (ii) maintain and promptly update your Registration Information from time to time as necessary, (iii) maintain the security of your Digital Wallet and accept all risks of unauthorized access thereto, and (iv) immediately notify us if you discover or otherwise suspect any security breaches related to the Service or your Digital Wallet. DFlow may require you to provide additional information and documents at the request of any competent authority or in order to help DFlow comply with applicable law, regulation, or policy, including laws related to anti-laundering (legalization) of incomes obtained by criminal means, or for counteracting financing of terrorism. DFlow may also require you to provide additional information and documents in cases where it has reasons to believe that:
● Your Digital Wallet is being used for money laundering or for any other illegal activity;
● You have concealed or reported false identification information and other Registration Information; or
● Transactions effected via your Digital Wallet were effected in breach of these Terms.
In such cases, DFlow, in its sole discretion, may disable your ability to use the Service until such requested additional information and documents have been reviewed by DFlow and accepted as satisfying the requirements of applicable law, regulation, or policy. If you do not provide complete and accurate information and documents in response to such a request, DFlow may refuse to provide any Digital Asset, Content, product, service, and/or further access to the Service to you.
b. User Agreements. You agree that you will not:
● buy, sell, rent, or lease access to the Service without our written permission;
● attempt to use the Service after removal by us; or
● access or try to access the Service through unauthorized third party applications or clients.
c. Consent to Electronic Communications. By connecting a Digital Wallet, you consent to receive electronic communications from DFlow (e.g., via email, message to such Digital Wallet, discord, or by posting notices to the Service). These communications may include notices about your use of the Service (e.g., transactional information) and are part of your relationship with us. You agree that any notices, agreements, disclosures or other communications that we send to you electronically will satisfy any legal communication requirements, including, but not limited to, any requirements that such communications be in writing. You should maintain copies of electronic communications from us by printing a paper copy or saving an electronic copy. We have no obligation to store for your later use or access any such electronic communications that we make to you. We may also send you promotional communications via email, including, but not limited to, newsletters, special offers, surveys and other news and information we think will be of interest to you. You may opt out of receiving these promotional emails at any time by following the unsubscribe instructions provided therein.
d. User Representations and Warranties. When you connect a Digital Wallet to the Service, you hereby represent and warrant, to and for the benefit of DFlow and its affiliates, as follows:
● You have all requisite capacity, power and authority to enter into and perform your obligations under these Terms, including to access the Service, and deploy any User Assets. The execution, delivery and performance of, and the performance of your obligations under, these Terms have been duly authorized by all necessary action on your part and on the part of any entity on behalf of which you are entering into these Terms, and no other proceedings are necessary to authorize the execution, delivery or performance of your obligations under these Terms.
● These Terms constitute your legal, valid and binding obligation, enforceable against you in accordance with these Terms.
● All Registration Information and other information provided to DFlow by you is accurate and complete. None of: (i) you; (ii) any affiliate of any entity on behalf of which you are entering into these Terms; (iii) any other person having a beneficial interest in any entity on behalf of which you are entering into these Terms (or in any affiliate thereof); or (iv) any person for whom you are acting as agent or nominee in connection with these Terms is: (A) a country, territory, entity or individual named on an OFAC list as provided at [http://www.treas.gov/ofac](http://www.treas.gov/ofac), or any person or entity prohibited under the OFAC programs, regardless of whether or not they appear on the OFAC list; or (B) a senior foreign political figure, or any immediate family member or close associate of a senior foreign political figure.
● You are sophisticated, experienced and knowledgeable in the matters contemplated by these Terms. Additionally, you have conducted an independent investigation of the Service and the matters contemplated by these Terms, have formed your own independent judgment regarding the benefits and risks of and necessary and desirable practices regarding the foregoing and, in making the determination to use the Service, you have relied solely on the results of such investigation and such independent judgment. Without limiting the generality of the foregoing, you understand, acknowledge and agree that the legal requirements pertaining to blockchain technologies and Digital Assets generally are evolving, and you have conducted an independent investigation of such potentially applicable legal requirements and the resulting risks and uncertainties. You hereby irrevocably disclaim and disavow reliance upon any statements or representations made by or on behalf of, or information made available by, DFlow, in determining to enter into these Terms and use the Service.
● There is no legal proceeding pending that relates to your activities relating to buying, selling, staking, or otherwise using Users Assets, Digital Assets or any other token- or Digital Asset- trading or blockchain technology related activities.
● You have not failed to comply with, and have not violated, any applicable legal requirement relating to any blockchain technologies or token-trading activities. No investigation or review by any governmental entity is pending or, to your knowledge, has been threatened against or with respect to you, nor does any government order or action prohibit you or any of your representatives from engaging in or continuing any conduct, activity or practice relating to Digital Assets.
e. Responsibility for Fees. You must provide all equipment and software necessary to connect to the Service. You are solely responsible for any fees, including Internet connection or mobile fees, that you incur when accessing the Service.
7. PRICING; PAYMENTS
a. General. All pricing and payment terms are as indicated at point of sale or otherwise on the Service, and any payment obligations you incur are binding at the time of the applicable Transaction or other use of the Service.
b. Interacting with the DFlow Protocol. Once you draft and sign a transaction message through your connected Digital Wallet, your Bid or Sale Offer for Order Flow will be added to the Platform. If such Bid or Sale Offer is accepted, the Transaction will be added, as applicable, to the applicable DeFi Platform, using the DFlow Protocol.
c. Gas Fees. You are solely responsible for ensuring that any payment made by you is sufficient to cover any Gas Fee required to complete the Transaction. “Gas Fees” are transaction fees determined by market conditions on the applicable blockchain network, including the Platform, at the time you effect a Transaction, and may not be determined, set, or charged by DFlow.
d. Payment Currency. You may not substitute any other currency (including any other cryptocurrency) for the currency in which you have contracted to pay at the time you entered into an agreement. For clarity, no fluctuation in the value of any currency, whether cryptocurrency or otherwise, shall impact or excuse your obligations with respect to any payment obligation. Whether a particular cryptocurrency is accepted as a payment method by DFlow is subject to change at any time in DFlow’s sole discretion. DFlow may add or change any supported blockchains or payment processing services at any time in its sole discretion. All such services may be subject to additional terms and conditions.
8. OWNERSHIP
a. Content. Unless otherwise indicated in writing by us, the Service and all content and other materials contained therein, including, without limitation, the DFlow logo and all designs, text, graphics, pictures, information, data, software, sound files, other files and the selection and arrangement thereof (collectively, “Content”) are the proprietary property of DFlow or our affiliates, and licensors, as applicable. You and other users, and not DFlow, are responsible for all Content made available by you and such other users (“User Content”).
b. Third-Party Licenses. Notwithstanding anything to the contrary in these Terms, the Service and Content may include software components provided by DFlow or its affiliates or a third party that are subject to separate license terms, in which case those license terms will govern such software components.
c. License to Service and Content. You are hereby granted a limited, revocable, nonexclusive, nontransferable, non-assignable, non-sublicensable, “as-is” license to access and use the Service and Content for your own personal, non-commercial use; provided, however, that such license is subject to these Terms and does not include any right to (i) sell, resell, or use commercially the Service or Content, (ii) distribute, publicly perform, or publicly display any Content, (iii) modify or otherwise make any derivative uses of the Service or Content, or any portion thereof, (iv) use any data mining, robots, or similar data gathering or extraction methods, (v) download (other than page caching) any portion of the Service or Content, except as expressly permitted by us, and (vi) use the Service or Content other than for their intended purposes. This license is subject to your compliance with the Acceptable Use Policy set forth in Section 10 below.
d. Your User Content. DFlow does not claim ownership of your User Content. However, when you make available any User Content on or to the Service, you represent that you own and/or have sufficient rights to such User Content to grant the license set forth in Section 8(e).
e. License to Your User Content. You grant DFlow a non-exclusive, transferable, perpetual, irrevocable, worldwide, fully-paid, royalty-free, sublicensable (through multiple tiers of sublicensees) right (including any moral rights) and license to use, copy, reproduce, modify, adapt, prepare derivative works from, translate, distribute, publicly perform, publicly display and derive revenue or other remuneration from your User Content (in whole or in part) for the purposes of operating and providing the Service to you and to our other users.
f. Feedback. You agree that submission of any ideas, suggestions, documents, and/or proposals to DFlow through its suggestion, feedback, forum, or similar pages (“Feedback”) is at your own risk and that DFlow has no obligations (including without limitation obligations of confidentiality) with respect to such Feedback. You represent and warrant that you have all rights necessary to submit the Feedback. You hereby grant to DFlow a fully paid, royalty-free, perpetual, irrevocable, worldwide, non-exclusive, and fully sublicensable right and license to use, reproduce, perform, display, distribute, adapt, modify, re-format, create derivative works of, and otherwise commercially or non-commercially exploit in any manner, any and all Feedback, and to sublicense the foregoing rights, in connection with the operation and maintenance of the Service and/or DFlow’s business.
9. THIRD-PARTY SERVICES; THIRD-PARTY TERMS
a. Third-Party Services. The Service may contain links to third-party properties and applications, including without limitation certain DeFi Platforms (collectively, “Third-Party Services”). When you click on a link to a Third-Party Service, you are subject to the terms and conditions (including privacy policies) of another property or application. DFlow is not responsible for any Third-Party Services. DFlow provides links to these Third-Party Services only as a convenience and does not review, approve, monitor, endorse, warrant, or make any representations with respect to Third-Party Services, or their products or services. You use all links in Third-Party Services at your own risk. When you leave our Service, our Terms and policies no longer govern. You should review all applicable agreements and policies, including privacy and data gathering practices, of any Third-Party Services, and should make whatever investigation you feel necessary or appropriate before proceeding with any Transaction with any third party.
b. Chatbot. The Service may include a chatbot powered by generative AI and machine learning (“Chatbot”). The Chatbot may use one or more Third-Party Services to respond to your messages. By using the Chatbot, you hereby consent and authorize DFlow to share any Content or other information you provide to the Chatbot with the applicable Third-Party Services in order to complete your request. YOU, AND NOT DFLOW, SHALL BE SOLELY RESPONSIBLE FOR YOUR USE OF THE CHATBOT. YOU ACKNOWLEDGE AND AGREE THAT ANY CONDUCT YOU ENGAGE IN AS A RESULT OF THE INFORMATION PROVIDED BY THE CHATBOT IS AT YOUR OWN RISK. BECAUSE CHATBOTS UTILIZE ARTIFICIAL INTELLIGENCE TO COMMUNICATE WITH YOU, OUR CHATBOT(S) MAY PROVIDE INFORMATION THAT IS AN INACCURATE OR INAPPROPRIATE RESPONSE TO YOUR REQUESTS IN ITS INTERACTIONS WITH YOU. YOU AGREE THAT DFLOW WILL NOT BE LIABLE TO YOU OR ANY THIRD PARTY FOR THE CHATBOT PROVIDING INACCURATE OR INAPPROPRIATE INFORMATION TO YOU. You further acknowledge and agree that when you interact with the Chatbot you grant DFlow and the applicable Third-Party Service provider a perpetual, irrevocable, fully-paid, royalty-free right and license to use any Content provided by you to train, develop, enhance, evolve and improve the Chatbot and applicable Third-Party Service and the underlying artificial intelligence models, algorithms and related technology, products and services (including for labeling, classification, content moderation and model training purposes).
c. Third-Party Application Access. With respect to any Application accessed through or downloaded from the Apple App Store (an “App Store Sourced Application”), you shall only use the App Store Sourced Application (i) on an Apple-branded product that runs the iOS (Apple’s proprietary operating system) and (ii) as permitted by the “Usage Rules” set forth in the Apple Media Terms of Service, except that such App Store Sourced Application may be accessed, acquired, and used by other accounts associated with the purchaser via Apple’s Family Sharing function, volume purchasing, or Legacy Contacts function. Notwithstanding the first sentence in this section, with respect to any Application accessed through or downloaded from the Google Play store (a “Google Play Sourced Application”), you may have additional license rights with respect to use of the Application on a shared basis within your designated family group.
d. Accessing and Downloading the Application from the Apple App Store. The following applies to any App Store Sourced Application accessed through or downloaded from the Apple App Store:
e. You acknowledge and agree that (i) this Agreement is concluded between you and DFlow only, and not Apple, and (ii) DFlow, not Apple, is solely responsible for the App Store Sourced Application and content thereof. Your use of the App Store Sourced Application must comply with the App Store Terms of Service.
f. You acknowledge that Apple has no obligation whatsoever to furnish any maintenance and support services with respect to the App Store Sourced Application.
g. In the event of any failure of the App Store Sourced Application to conform to any applicable warranty, you may notify Apple, and Apple will refund the purchase price for the App Store Sourced Application to you and to the maximum extent permitted by applicable law, Apple will have no other warranty obligation whatsoever with respect to the App Store Sourced Application. As between DFlow and Apple, any other claims, losses, liabilities, damages, costs or expenses attributable to any failure to conform to any warranty will be the sole responsibility of DFlow.
h. You and DFlow acknowledge that, as between DFlow and Apple, Apple is not responsible for addressing any claims you have or of any third party relating to the App Store Sourced Application or your possession and use of the App Store Sourced Application, including, but not limited to: (i) product liability claims; (ii) any claim that the App Store Sourced Application fails to conform to any applicable legal or regulatory requirement; and (iii) claims arising under consumer protection or similar legislation.
i. You and DFlow acknowledge that, in the event of any third-party claim that the App Store Sourced Application or your possession and use of that App Store Sourced Application infringes that third party’s intellectual property rights, as between DFlow and Apple, DFlow, not Apple, will be solely responsible for the investigation, defense, settlement and discharge of any such intellectual property infringement claim to the extent required by this Agreement.
j. You and DFlow acknowledge and agree that Apple, and Apple’s subsidiaries, are third-party beneficiaries of this Agreement as related to your license of the App Store Sourced Application, and that, upon your acceptance of the terms and conditions of this Agreement, Apple will have the right (and will be deemed to have accepted the right) to enforce this Agreement as related to your license of the App Store Sourced Application against you as a third-party beneficiary thereof.
k. Without limiting any other terms of this Agreement, you must comply with all applicable third-party terms of agreement when using the App Store Sourced Application.
10. ACCEPTABLE USE POLICY
You agree that you are solely responsible for your conduct while accessing or using the Service. You agree that you will abide by these Terms and will not:
a. Use the Service in any manner that could interfere with, disrupt, negatively affect or inhibit other users from fully enjoying the Service, or that could damage, disable, overburden or impair the functioning of the Service in any manner;
b. Develop, utilize, or disseminate any software, or interact with any API in any manner, that could damage, harm, or impair the Service;
c. Reverse engineer any aspect of the Service, or do anything that might discover source code or bypass or circumvent measures employed to prevent or limit access to any service, area, or code of the Service;
d. Use any robot, spider, crawler, scraper, script, browser extension, offline reader, or other automated means or interface not authorized by us to access the Service, extract data or otherwise interfere with or modify the rendering of Service pages or functionality;
e. Collect or harvest data from our Service that would allow you to contact individuals, companies, or other persons or entities, or use any such data to contact such entities;
f. Use data collected from our Service for any direct marketing activity (including without limitation, email marketing, SMS marketing, telemarketing, unsolicited airdrops, and direct marketing);
g. Bypass or ignore instructions that control all automated access to the Service;
h. Use the Service for any illegal or unauthorized purpose, or engage in, encourage, or promote any activity that violates any applicable law or these Terms;
i. Use the Service to carry out any illegal activities, or use the Digital Wallet or User Assets that you use in connection with the Service in connection with any illegal activities, including but not limited to money laundering, terrorist financing or deliberately engaging in activities designed to adversely affect the performance of the Service;
j. Engage in or knowingly facilitate any “wash trading,” “pump and dump trading,” “ramping,” “cornering” or fraudulent trading activities, including:
● trading a Digital Asset, or Digital Asset Order Flow, at successively lower or higher prices for the purpose of creating or inducing a false, misleading or artificial appearance of activity in such Digital Asset, unduly or improperly influencing the market price for such Digital Asset or establishing a price which does not reflect the true state of the market in such Digital Asset; or
● executing or causing the execution of any Transaction in a User Asset which involves no material change in the beneficial ownership thereof.
k. Use the Service to carry out any financial activities subject to registration or licensing, including but not limited to using the Service to transact in securities, commodities futures, trading of commodities on a leveraged, margined or financed basis, binary options (including prediction-market transactions), real estate or real estate leases, equipment leases, debt financings, equity financings or other similar transactions.
11. INVESTIGATIONS
If DFlow becomes aware of any possible violations by you of these Terms, DFlow reserves the right to investigate such violations. If, as a result of the investigation, DFlow believes that criminal activity may have occurred, DFlow reserves the right to refer the matter to, and to cooperate with, any and all applicable legal authorities. DFlow is entitled, except to the extent prohibited by applicable law, to disclose to third parties any information or materials in DFlow’s possession, including in order to (i) comply with applicable laws, legal process or governmental request; (ii) enforce these Terms, (iii) respond to your requests for customer service, or (iv) protect the rights, property or personal safety of DFlow, its users, or the public, as DFlow in its sole discretion believes to be necessary or appropriate. By agreeing to these Terms, you hereby provide your irrevocable consent to such monitoring. You understand, acknowledge, and agree that you have no expectation of privacy concerning your use of the Service, including without limitation text, voice, or video communications.
12. RELEASE
You hereby release and forever discharge DFlow and our officers, employees, agents, successors, and assigns (the “DFlow Entities”) from, and hereby waive and relinquish, each and every past, present and future dispute, claim, controversy, demand, right, obligation, liability, action and cause of action of every kind and nature (including personal injuries, death, and property damage), that has arisen or arises directly or indirectly out of, or that relates directly or indirectly to, the Service (including any interactions with, or act or omission of, any DeFi Platform). IF YOU ARE A CALIFORNIA RESIDENT, YOU HEREBY WAIVE CALIFORNIA CIVIL CODE SECTION 1542 IN CONNECTION WITH THE FOREGOING, WHICH STATES: “A GENERAL RELEASE DOES NOT EXTEND TO CLAIMS WHICH THE CREDITOR OR RELEASING PARTY DOES NOT KNOW OR SUSPECT TO EXIST IN HIS OR HER FAVOR AT THE TIME OF EXECUTING THE RELEASE, WHICH IF KNOWN BY HIM OR HER MUST HAVE MATERIALLY AFFECTED HIS OR HER SETTLEMENT WITH THE DEBTOR OR RELEASED PARTY.”
13. ASSUMPTION OF RISK RELATED TO BLOCKCHAIN
You acknowledge and agree that:
a. The prices of Digital Assets are extremely volatile. Fluctuations in the price of other digital assets could materially and adversely affect the value of your User Assets, including your Digital Assets.
b. You are solely responsible for determining what, if any, taxes apply to any Transaction. Neither DFlow nor any other DFlow Entity is responsible for determining the taxes that may apply to Transactions.
c. User Assets exist and can be transferred only by virtue of the ownership record maintained on the blockchain supporting such User Assets. Any transfer of User Assets occurs within the supporting blockchain and/or as facilitated by the DFlow Protocol, and not on the Service.
d. There are risks associated with using digital currency, including but not limited to the risk of hardware, software and Internet connections, the risk of malicious software introduction, and the risk that third parties may obtain unauthorized access to information stored within your Digital Wallet.
e. There are risks associated with use of the DFlow Protocol, including but not limited to security flaws and vulnerabilities, bugs, and other factors. DFlow makes no representations as to the security of the DFlow Protocol, and you enter into any Transaction using the DFlow Protocol at your own risk.
f. DFlow does not monitor, and is not liable to you for, any user activity in connection with the Service or the DFlow Protocol. DFlow cannot control, and makes no representations with respect to, any DeFi Platform.
g. The legal and regulatory regime governing blockchain technologies, cryptocurrencies, and tokens is uncertain, and new regulations or policies may materially adversely affect the development of the Service and the utility of Digital Assets.
h. There are risks associated with user-generated assets, including but not limited to, the risk of purchasing counterfeit assets, mislabeled assets, assets that are vulnerable to metadata decay, assets on smart contracts with bugs, and assets that may become untransferable.
i. DFlow reserves the right to hide collections, contracts, and assets that DFlow suspects or believes may violate these Terms. Digital Assets you deploy may become inaccessible on the Service. Under no circumstances shall the inability to view your assets on the Service serve as grounds for a claim against DFlow.
j. DFlow has no responsibility for the User Assets, including any Digital Assets, deployed on or through the Service. DFlow does not investigate and cannot guarantee or warrant the legality or value of any User Asset made available on the Service. For the avoidance of doubt, DFlow shall have no responsibility for any failure of any user to comply with any terms regarding the User Asset furnished by or on behalf of that user and available via the Service.
14. INDEMNIFICATION
To the fullest extent permitted by applicable law, you agree to indemnify, defend, and hold harmless DFlow and the DFlow Entities from and against all actual or alleged third party claims, damages, awards, judgments, losses, liabilities, obligations, penalties, interest, fees, expenses (including, without limitation, attorneys’ fees and expenses) and costs (including, without limitation, court costs, costs of settlement, and costs of or associated with pursuing indemnification and insurance), of every kind and nature whatsoever arising out of or related to these Terms or your use of the Service or the Service, whether known or unknown, foreseen or unforeseen, matured or unmatured, or suspected or unsuspected, in law or equity, whether in tort, contract or otherwise (collectively, “Claims”), including, but not limited to, damages to property or personal injury, that are caused by, arise out of or are related to (a) your use or misuse of the Service or any User Assets, (b) any Feedback you provide, (c) your violation of these Terms, and (d) your violation of the rights of any third party, including another user. You agree to promptly notify DFlow of any third-party Claims and cooperate with the DFlow Entities in defending such Claims. You further agree that the DFlow Entities shall have control of the defense or settlement of any third-party Claims. THIS INDEMNITY IS IN ADDITION TO, AND NOT IN LIEU OF, ANY OTHER INDEMNITIES SET FORTH IN A SEPARATE WRITTEN AGREEMENT BETWEEN YOU AND DFLOW.
15. DISCLAIMERS
THE SERVICE IS PROVIDED ON AN “AS IS” AND “AS AVAILABLE” BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. DFLOW (AND ITS SUPPLIERS) MAKE NO WARRANTY THAT THE SERVICE: (A) WILL MEET YOUR REQUIREMENTS; (B) WILL BE AVAILABLE ON AN UNINTERRUPTED, TIMELY, SECURE, OR ERROR-FREE BASIS; OR (C) WILL BE ACCURATE, RELIABLE, COMPLETE, LEGAL, OR SAFE. DFLOW DISCLAIMS ALL OTHER WARRANTIES OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT AS TO THE SERVICE OR ANY CONTENT CONTAINED THEREIN. DFLOW DOES NOT REPRESENT OR WARRANT THAT THE SERVICE OR CONTENT ON THE SERVICE IS ACCURATE, COMPLETE, RELIABLE, CURRENT, OR ERROR-FREE. WE WILL NOT BE LIABLE FOR ANY LOSS OF ANY KIND FROM ANY ACTION TAKEN OR TAKEN IN RELIANCE ON MATERIAL OR INFORMATION, CONTAINED ON THE SERVICE. WHILE DFLOW ATTEMPTS TO MAKE YOUR ACCESS TO AND USE OF THE SERVICE AND CONTENT SAFE, DFLOW CANNOT AND DOES NOT REPRESENT OR WARRANT THAT THE SERVICE, CONTENT, OR ANY USER ASSETS LISTED ON OUR SERVICE ARE FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS. WE CANNOT GUARANTEE THE SECURITY OF ANY DATA THAT YOU DISCLOSE ONLINE. YOU ACCEPT THE INHERENT SECURITY RISKS OF PROVIDING INFORMATION AND DEALING ONLINE OVER THE INTERNET AND WILL NOT HOLD US RESPONSIBLE FOR ANY BREACH OF SECURITY UNLESS IT IS DUE TO OUR GROSS NEGLIGENCE.
WE WILL NOT BE RESPONSIBLE OR LIABLE TO YOU FOR ANY LOSSES YOU SUSTAIN AS A RESULT OF YOUR USE OF THE SERVICE. WE TAKE NO RESPONSIBILITY FOR, AND WILL NOT BE LIABLE TO YOU FOR, ANY USE OF USER ASSETS, INCLUDING BUT NOT LIMITED TO ANY LOSSES, DAMAGES OR CLAIMS ARISING FROM: (I) USER ERROR SUCH AS FORGOTTEN PASSWORDS, INCORRECTLY CONSTRUCTED TRANSACTIONS, OR MISTYPED ADDRESSES; (II) SERVER FAILURE OR DATA LOSS; (III) CORRUPTED DIGITAL WALLET FILES; (IV) UNAUTHORIZED ACCESS TO APPLICATIONS; (V) ANY UNAUTHORIZED THIRD PARTY ACTIVITIES, INCLUDING WITHOUT LIMITATION THE USE OF VIRUSES, PHISHING, BRUTEFORCING OR OTHER MEANS OF ATTACK AGAINST THE SERVICE OR USER ASSETS; (VI) YOUR USE OF OR FAILURE TO USE THE DFLOW PROTOCOL; OR (VII) ANY USE OR MISUSE OF THE SERVICE BY YOU OR ANY THIRD PARTY.
NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED FROM DFLOW OR THROUGH THE SERVICE WILL CREATE ANY WARRANTY NOT EXPRESSLY MADE HEREIN.
FROM TIME TO TIME, DFLOW MAY OFFER NEW “BETA” FEATURES OR TOOLS. ALL SUCH FEATURES OR TOOLS ARE OFFERED “AS IS” AND WITH ALL FAULTS, SOLELY FOR EXPERIMENTAL PURPOSES AND WITHOUT ANY WARRANTY OF ANY KIND, AND MAY BE MODIFIED OR DISCONTINUED AT DFLOW’S SOLE DISCRETION. THE PROVISIONS OF THIS SECTION APPLY WITH FULL FORCE TO SUCH FEATURES OR TOOLS.
USER ASSETS ARE INTANGIBLE ASSETS THAT EXIST ONLY BY VIRTUE OF THE OWNERSHIP RECORD MAINTAINED IN THE BLOCKCHAIN NETWORK. ANY TRANSFER OF TITLE THAT MIGHT OCCUR IN ANY UNIQUE DIGITAL ASSET OCCURS ON THE DECENTRALIZED LEDGER WITHIN THE BLOCKCHAIN PLATFORM. WE DO NOT GUARANTEE THAT DFLOW OR ANY DFLOW ENTITY CAN EFFECT THE TRANSFER OF TITLE OR RIGHT IN ANY USER ASSETS. WE CANNOT AND DO NOT GUARANTEE THAT ANY USER ASSET WILL HAVE OR RETAIN ANY INHERENT VALUE, OR THAT YOU WILL BE ABLE TO RECEIVE OR ACCESS ANY USER ASSET ACCESS PRIVILEGES OR OTHER BENEFITS ASSOCIATED WITH ANY USER ASSET THAT YOU BUY OR SELL THROUGH THE SERVICE.
DFLOW IS NOT AN INVESTMENT ADVISOR. NEITHER DFLOW NOR ITS SUPPLIERS OR LICENSORS SHALL BE RESPONSIBLE FOR INVESTMENT AND OTHER FINANCIAL DECISIONS, OR DAMAGES, OR OTHER LOSSES RESULTING FROM USE OF THE SERVICES. NEITHER DFLOW NOR ITS SUPPLIERS OR LICENSORS SHALL BE CONSIDERED AN “EXPERT” UNDER THE SECURITIES ACT OF 1933. NEITHER DFLOW NOR ITS SUPPLIERS OR LICENSORS WARRANT THAT THIS WEBSITE COMPLIES WITH THE REQUIREMENTS OF THE FINANCIAL INDUSTRY REGULATORY AUTHORITY, THE SECURITIES AND EXCHANGE COMMISSION OR ANY SIMILAR ORGANIZATION OR REGULATOR OR WITH THE SECURITIES LAWS OF ANY JURISDICTION.
YOU ACKNOWLEDGE AND AGREE THAT DFLOW PARTIES ARE NOT LIABLE, AND YOU AGREE NOT TO SEEK TO HOLD DFLOW PARTIES LIABLE, FOR THE CONDUCT OF THIRD PARTIES, INCLUDING OPERATORS OF EXTERNAL SITES AND DEFI PLATFORMS, AND THAT THE RISK OF INJURY FROM SUCH THIRD PARTIES RESTS ENTIRELY WITH YOU. DFLOW SHALL BE UNDER NO OBLIGATION TO INQUIRE INTO AND SHALL NOT BE LIABLE FOR ANY DAMAGES, OTHER LIABILITIES OR HARM TO ANY PERSON OR ENTITY RELATING TO ANY LOSSES, DELAYS, FAILURES, ERRORS, INTERRUPTIONS OR LOSS OF DATA OCCURRING DIRECTLY OR INDIRECTLY BY REASON OF CIRCUMSTANCES BEYOND DFLOW’S CONTROL, INCLUDING WITHOUT LIMITATION THROUGH THE DEPLOYMENT OF USER ASSETS TO ANY DEFI PLATFORM IN CONNECTION WITH THE SERVICES.
DFlow is not responsible for any losses or harms sustained by you due to vulnerability or any kind of failure, abnormal behavior of software (e.g., wallet, smart contract), blockchains, or any other features of or inherent to the User Assets. DFlow is not responsible for casualties due to developers or representatives delay or failure to report any issues with any blockchain supporting User Assets, including without limitation forks, technical node issues, or any other issues that result in losses of any sort, including without limitation any issues arising from or related to the DFlow Protocol.
Nothing in these Terms shall exclude or limit liability of either party for fraud, death or bodily injury caused by negligence, violation of laws, or any other activity that cannot be limited or excluded under the laws applicable to your jurisdiction.
SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES IN CONTRACTS WITH CONSUMERS, SO THE ABOVE EXCLUSION(S) MAY NOT APPLY TO YOU.
16. LIMITATION OF LIABILITY
TO THE FULLEST EXTENT PERMITTED BY LAW, IN NO EVENT WILL DFLOW BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY LOST PROFIT OR ANY INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES ARISING FROM THESE TERMS, THE SERVICE, ANY USER ASSETS, ANY TRANSACTION, YOUR USE OF OR INABILITY TO USE THE DFLOW PROTOCOL FOR ANY PURPOSE, OR FOR ANY DAMAGES RELATED TO LOSS OF REVENUE, LOSS OF PROFITS, LOSS OF BUSINESS OR ANTICIPATED SAVINGS, LOSS OF USE, LOSS OF GOODWILL, OR LOSS OF DATA, AND WHETHER CAUSED BY TORT (INCLUDING NEGLIGENCE), BREACH OF CONTRACT, OR OTHERWISE, EVEN IF FORESEEABLE AND EVEN IF DFLOW HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ACCESS TO, AND USE OF, THE SERVICE IS UNDERTAKEN BY YOU AT YOUR OWN DISCRETION AND RISK, AND YOU WILL BE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR MOBILE DEVICE OR LOSS OF DATA RESULTING THEREFROM.
NOTWITHSTANDING ANYTHING TO THE CONTRARY CONTAINED HEREIN, IN NO EVENT SHALL THE MAXIMUM AGGREGATE LIABILITY OF DFLOW ARISING OUT OF OR IN ANY WAY RELATED TO THESE TERMS, YOUR ACCESS TO AND USE OF THE SERVICE, CONTENT (INCLUDING YOUR CONTENT), YOUR USE OF OR INABILITY TO USE THE DFLOW PROTOCOL, OR ANY USER ASSETS DEPLOYED OR VIEWED THROUGH THE SERVICE EXCEED THE GREATER OF (A) \$100 OR (B) THE AMOUNT PAID TO DFLOW BY YOU FOR THE SERVICE IN THE TRANSACTION OR INCIDENT THAT IS THE SUBJECT OF THE CLAIM.
Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so the above limitation or exclusion may not apply to you.
17. DISPUTE RESOLUTION. Please read this Arbitration Agreement (the “Arbitration Agreement”) carefully. It is part of your contract with DFlow and affects your rights. It contains procedures for MANDATORY BINDING ARBITRATION AND A CLASS ACTION WAIVER.
a. Applicability of Arbitration Agreement. Subject to the terms of this Arbitration Agreement, you and DFlow agree that any dispute, claim, disagreements arising out of or relating in any way to your access to or use of the Service, any communications you receive from us, any products (including any User Assets) used by you through or in connection with the Service, any use of or interaction with the DFlow Protocol (including any failure of the same) or the Terms and prior versions of the Terms, including claims and disputes that arose between us before the effective date of these Terms (each, a “Dispute”) will be resolved by binding arbitration, rather than in court, except that: (1) you and DFlow may assert claims or seek relief in small claims court if such claims qualify and remain in small claims court; and (2) you or DFlow may seek equitable relief in court for infringement or other misuse of intellectual property rights (such as trademarks, trade dress, domain names, trade secrets, copyrights, and patents). For purposes of this Arbitration Agreement, “Dispute” will also include disputes that arose or involve facts occurring before the existence of this or any prior versions of the Terms as well as claims that may arise after the termination of these Terms.
b. Informal Dispute Resolution. There might be instances when a Dispute arises between you and DFlow. If that occurs, DFlow is committed to working with you to reach a reasonable resolution. You and DFlow agree that good faith informal efforts to resolve Disputes can result in a prompt, low‐cost and mutually beneficial outcome. You and DFlow therefore agree that before either party commences arbitration against the other (or initiates an action in small claims court if a party so elects), we will personally meet and confer telephonically or via videoconference, in a good faith effort to resolve informally any Dispute covered by this Arbitration Agreement (“Informal Dispute Resolution Conference”). If you are represented by counsel, your counsel may participate in the conference, but you will also participate in the conference. The party initiating a Dispute must give notice to the other party in writing of its intent to initiate an Informal Dispute Resolution Conference (“Notice”), which shall occur within 45 days after the other party receives such Notice, unless an extension is mutually agreed upon by the parties. Notice to DFlow that you intend to initiate an Informal Dispute Resolution Conference should be sent by email to the contact information set forth in Section 18. The Notice must include: (1) your name, telephone number, mailing address, e‐mail address and/or Digital Wallet address (if you have one); (2) the name, telephone number, mailing address and e‐mail address of your counsel, if any; and (3) a description of your Dispute. The Informal Dispute Resolution Conference shall be individualized such that a separate conference must be held each time either party initiates a Dispute, even if the same law firm or group of law firms represents multiple users in similar cases, unless all parties agree; multiple individuals initiating a Dispute cannot participate in the same Informal Dispute Resolution Conference unless all parties agree. In the time between a party receiving the Notice and the Informal Dispute Resolution Conference, nothing in this Arbitration Agreement shall prohibit the parties from engaging in informal communications to resolve the initiating party’s Dispute. Engaging in the Informal Dispute Resolution Conference is a condition precedent and requirement that must be fulfilled before commencing arbitration. The statute of limitations and any filing fee deadlines shall be tolled while the parties engage in the Informal Dispute Resolution Conference process required by this section.
c. Waiver of Jury Trial. YOU AND DFLOW HEREBY WAIVE ANY CONSTITUTIONAL AND STATUTORY RIGHTS TO SUE IN COURT AND HAVE A TRIAL IN FRONT OF A JUDGE OR A JURY. You and DFlow are instead electing that all Disputes shall be resolved by arbitration under this Arbitration Agreement, except as specified in Subsection 16(a), above. There is no judge or jury in arbitration, and court review of an arbitration award is subject to very limited review.
d. Waiver of Class and Other Non-Individualized Relief. YOU AND DFLOW AGREE THAT, EXCEPT AS SPECIFIED IN SUBSECTION 16.i, EACH OF US MAY BRING CLAIMS AGAINST THE OTHER ONLY ON AN INDIVIDUAL BASIS AND NOT ON A CLASS, REPRESENTATIVE, OR COLLECTIVE BASIS, AND THE PARTIES HEREBY WAIVE ALL RIGHTS TO HAVE ANY DISPUTE BE BROUGHT, HEARD, ADMINISTERED, RESOLVED, OR ARBITRATED ON A CLASS, COLLECTIVE, REPRESENTATIVE, OR MASS ACTION BASIS. ONLY INDIVIDUAL RELIEF IS AVAILABLE, AND DISPUTES OF MORE THAN ONE CUSTOMER OR USER CANNOT BE ARBITRATED OR CONSOLIDATED WITH THOSE OF ANY OTHER CUSTOMER OR USER. Subject to this Arbitration Agreement, the arbitrator may award declaratory or injunctive relief only in favor of the individual party seeking relief and only to the extent necessary to provide relief warranted by the party’s individual claim. Nothing in this paragraph is intended to, nor shall it, affect the terms and conditions under the subsection 16.i entitled “Batch Arbitration.” Notwithstanding anything to the contrary in this Arbitration Agreement, if a court decides by means of a final decision, not subject to any further appeal or recourse, that the limitations of this subsection, “Waiver of Class and Other Non-Individualized Relief,” are invalid or unenforceable as to a particular claim or request for relief (such as a request for public injunctive relief), you and DFlow agree that that particular claim or request for relief (and only that particular claim or request for relief) shall be severed from the arbitration and may be litigated in the state or federal courts located in the State of California. All other Disputes shall be arbitrated or litigated in small claims court. This subsection does not prevent you or DFlow from participating in a class-wide settlement of claims.
e. Rules and Forum. The Terms evidence a transaction involving interstate commerce; and notwithstanding any other provision herein with respect to the applicable substantive law, the Federal Arbitration Act, 9 U.S.C. § 1 et seq., will govern the interpretation and enforcement of this Arbitration Agreement and any arbitration proceedings. If the Informal Dispute Resolution Conference process described above does not resolve satisfactorily within sixty (60) days after receipt of your Notice, you and DFlow agree that either party shall have the right to finally resolve the Dispute through binding arbitration. The arbitration will be administered by the American Arbitration Association (“AAA”), in accordance with the Consumer Arbitration Rules (the “AAA Rules”) then in effect, except as modified by this section of this Arbitration Agreement. The AAA Rules are currently available at [https://www.adr.org/sites/default/files/Consumer%20Rules.pdf](https://www.adr.org/sites/default/files/Consumer%20Rules.pdf). A party who wishes to initiate arbitration must provide the other party with a request for arbitration (the “Request”). The Request must include: (1) the name, telephone number, mailing address, e‐mail address of the party seeking arbitration (if applicable) as well as the applicable Digital Wallet address; (2) a statement of the legal claims being asserted and the factual bases of those claims; (3) a description of the remedy sought and an accurate, good‐faith calculation of the amount in controversy in United States Dollars; (4) a statement certifying completion of the Informal Dispute Resolution Conference process as described above; and (5) evidence that the requesting party has paid any necessary filing fees in connection with such arbitration. If the party requesting arbitration is represented by counsel, the Request shall also include counsel’s name, telephone number, mailing address, and email address. Such counsel must also sign the Request. By signing the Request, counsel certifies to the best of counsel’s knowledge, information, and belief, formed after an inquiry reasonable under the circumstances, that: (1) the Request is not being presented for any improper purpose, such as to harass, cause unnecessary delay, or needlessly increase the cost of dispute resolution; (2) the claims, defenses and other legal contentions are warranted by existing law or by a nonfrivolous argument for extending, modifying, or reversing existing law or for establishing new law; and (3) the factual and damages contentions have evidentiary support or, if specifically so identified, will likely have evidentiary support after a reasonable opportunity for further investigation or discovery. Unless you and DFlow otherwise agree, or the Batch Arbitration process discussed in subsection 16.i is triggered, the arbitration will be conducted in the county where you reside. Subject to the AAA Rules, the arbitrator may direct a limited and reasonable exchange of information between the parties, consistent with the expedited nature of the arbitration. If the AAA is not available to arbitrate, the parties will select an alternative arbitral forum. Your responsibility to pay any AAA fees and costs will be solely as set forth in the applicable AAA Rules. You and DFlow agree that all materials and documents exchanged during the arbitration proceedings shall be kept confidential and shall not be shared with anyone except the parties’ attorneys, accountants, or business advisors, and then subject to the condition that they agree to keep all materials and documents exchanged during the arbitration proceedings confidential.
f. Arbitrator. The arbitrator will be either a retired judge or an attorney licensed to practice law in the state of Florida and will be selected by the parties from the AAA’s roster of consumer dispute arbitrators. If the parties are unable to agree upon an arbitrator within thirty-five (35) days of delivery of the Request, then the AAA will appoint the arbitrator in accordance with the AAA Rules, provided that if the Batch Arbitration process under subsection 16.i is triggered, the AAA will appoint the arbitrator for each batch.
g. Authority of Arbitrator. The arbitrator shall have exclusive authority to resolve any Dispute, including, without limitation, disputes arising out of or related to the interpretation or application of the Arbitration Agreement, including the enforceability, revocability, scope, or validity of the Arbitration Agreement or any portion of the Arbitration Agreement, except for the following: (1) all Disputes arising out of or relating to the subsection entitled “Waiver of Class and Other Non-Individualized Relief,” including any claim that all or part of the subsection entitled “Waiver of Class and Other Non-Individualized Relief” is unenforceable, illegal, void or voidable, or that such subsection entitled “Waiver of Class and Other Non-Individualized Relief” has been breached, shall be decided by a court of competent jurisdiction and not by an arbitrator; (2) except as expressly contemplated in the subsection entitled “Batch Arbitration,” all Disputes about the payment of arbitration fees shall be decided only by a court of competent jurisdiction and not by an arbitrator; (3) all Disputes about whether either party has satisfied any condition precedent to arbitration shall be decided only by a court of competent jurisdiction and not by an arbitrator; and (4) all Disputes about which version of the Arbitration Agreement applies shall be decided only by a court of competent jurisdiction and not by an arbitrator. The arbitration proceeding will not be consolidated with any other matters or joined with any other cases or parties, except as expressly provided in the subsection entitled “Batch Arbitration.” The arbitrator shall have the authority to grant motions dispositive of all or part of any Dispute. The arbitrator shall issue a written award and statement of decision describing the essential findings and conclusions on which the award is based, including the calculation of any damages awarded. The award of the arbitrator is final and binding upon you and us. Judgment on the arbitration award may be entered in any court having jurisdiction.
h. Attorneys’ Fees and Costs. The parties shall bear their own attorneys’ fees and costs in arbitration unless the arbitrator finds that either the substance of the Dispute or the relief sought in the Request was frivolous or was brought for an improper purpose (as measured by the standards set forth in Federal Rule of Civil Procedure 11(b)). If you or DFlow need to invoke the authority of a court of competent jurisdiction to compel arbitration, then the party that obtains an order compelling arbitration in such action shall have the right to collect from the other party its reasonable costs, necessary disbursements, and reasonable attorneys’ fees incurred in securing an order compelling arbitration. The prevailing party in any court action relating to whether either party has satisfied any condition precedent to arbitration, including the Informal Dispute Resolution Conference process, is entitled to recover their reasonable costs, necessary disbursements, and reasonable attorneys’ fees and costs.
i. Batch Arbitration. To increase the efficiency of administration and resolution of arbitrations, you and DFlow agree that in the event that there are one hundred (100) or more individual Requests of a substantially similar nature filed against DFlow by or with the assistance of the same law firm, group of law firms, or organizations, within a thirty (30) day period (or as soon as possible thereafter), the AAA shall (1) administer the arbitration demands in batches of 100 Requests per batch (plus, to the extent there are less than 100 Requests left over after the batching described above, a final batch consisting of the remaining Requests); (2) appoint one arbitrator for each batch; and (3) provide for the resolution of each batch as a single consolidated arbitration with one set of filing and administrative fees due per side per batch, one procedural calendar, one hearing (if any) in a place to be determined by the arbitrator, and one final award (“Batch Arbitration”). All parties agree that Requests are of a “substantially similar nature” if they arise out of or relate to the same event or factual scenario and raise the same or similar legal issues and seek the same or similar relief. To the extent the parties disagree on the application of the Batch Arbitration process, the disagreeing party shall advise the AAA, and the AAA shall appoint a sole standing arbitrator to determine the applicability of the Batch Arbitration process (“Administrative Arbitrator”). In an effort to expedite resolution of any such dispute by the Administrative Arbitrator, the parties agree the Administrative Arbitrator may set forth such procedures as are necessary to resolve any disputes promptly. The Administrative Arbitrator’s fees shall be paid by DFlow. You and DFlow agree to cooperate in good faith with the AAA to implement the Batch Arbitration process including the payment of single filing and administrative fees for batches of Requests, as well as any steps to minimize the time and costs of arbitration, which may include: (1) the appointment of a discovery special master to assist the arbitrator in the resolution of discovery disputes; and (2) the adoption of an expedited calendar of the arbitration proceedings. This Batch Arbitration provision shall in no way be interpreted as authorizing a class, collective and/or mass arbitration or action of any kind, or arbitration involving joint or consolidated claims under any circumstances, except as expressly set forth in this provision.
j. 30-Day Right to Opt Out. You have the right to opt out of the provisions of this Arbitration Agreement by sending written notice of your decision to opt out to the address set forth in Section 18, within thirty (30) days after first becoming subject to this Arbitration Agreement. Your notice must include your name and address, email address, Digital Wallet address (if you have one), and an unequivocal statement that you want to opt out of this Arbitration Agreement. If you opt out of this Arbitration Agreement, all other parts of these Terms will continue to apply to you. Opting out of this Arbitration Agreement has no effect on any other arbitration agreements that you may currently have, or may enter in the future, with us.
k. Invalidity, Expiration. Except as provided in the subsection entitled “Waiver of Class and Other Non-Individualized Relief”, if any part or parts of this Arbitration Agreement are found under the law to be invalid or unenforceable, then such specific part or parts shall be of no force and effect and shall be severed and the remainder of the Arbitration Agreement shall continue in full force and effect. You further agree that any Dispute that you have with DFlow as detailed in this Arbitration Agreement must be initiated via arbitration within the applicable statute of limitation for that claim or controversy, or it will be forever time barred. Likewise, you agree that all applicable statutes of limitation will apply to such arbitration in the same manner as those statutes of limitation would apply in the applicable court of competent jurisdiction.
l. Modification. Notwithstanding any provision in these Terms to the contrary, we agree that if DFlow makes any future material change to this Arbitration Agreement, it will notify you. Unless you reject the change within thirty (30) days of such change become effective by writing to DFlow at the address set forth in Section 18, your continued use of the Service following the posting of changes to this Arbitration Agreement constitutes your acceptance of any such changes. Changes to this Arbitration Agreement do not provide you with a new opportunity to opt out of the Arbitration Agreement if you have previously agreed to a version of these Terms and did not validly opt out of arbitration. If you reject any change or update to this Arbitration Agreement, and you were bound by an existing agreement to arbitrate Disputes arising out of or relating in any way to your access to or use of the Services, any communications you receive, or these Terms, the provisions of this Arbitration Agreement as of the date you first accepted the Terms (or accepted any subsequent changes to these Terms) remain in full force and effect. DFlow will continue to honor any valid opt outs of the Arbitration Agreement that you made to a prior version of these Terms.
m. Confidentiality. All aspects of the arbitration proceeding, including but not limited to the award of the arbitrator and compliance therewith, shall be strictly confidential. The parties agree to maintain confidentiality unless otherwise required by law. This paragraph shall not prevent a party from submitting to a court of law any information necessary to enforce this Agreement, to enforce an arbitration award, or to seek injunctive or equitable relief.
n. Survival of Agreement. This Arbitration Agreement will survive the termination of your relationship with DFlow.
18. GENERAL
You may terminate these Terms by disconnecting your Digital Wallet, ceasing all further use of the Service, and sending us notice of your intention to terminate these Terms at the address set forth in Section 18, below. We reserve the right in our sole discretion to modify, suspend, or discontinue the Service, or any features or parts thereof, whether temporarily or permanently, at any time with or without notice to you in our sole discretion. All sections of these Terms intended by their nature to survive, including without your indemnification obligations, all disclaimers, your release of DFlow, and our limitation of liability hereunder, shall survive such termination. These Terms, and your access to, and use of, the Service, shall be governed by and construed and enforced in accordance with the laws of the state of California, without regard to any conflict of law rules or principles that would cause the application of the laws of any other jurisdiction. Any dispute between the parties that is not subject to arbitration or cannot be heard in small claims court, shall be resolved in the courts of California. Notwithstanding anything contained in these Terms, we reserve the right, without notice and in our sole discretion, to terminate your right to access or use the Service at any time and for any or no reason, and you acknowledge and agree that we shall have no liability or obligation to you in such event and that you will not be entitled to a refund of any amounts that you have already paid to us, to the fullest extent permitted by applicable law. If any term, clause or provision of these Terms is held invalid or unenforceable, then that term, clause or provision will be severable from these Terms and will not affect the validity or enforceability of any remaining part of that term, clause or provision, or any other term, clause or provision of these Terms. Your relationship to DFlow is that of an independent contractor, and neither party is an agent or partner of the other. These Terms, and any rights and licenses granted hereunder, may not be transferred or assigned by you without the prior written consent of DFlow. DFlow’s failure to assert any right or provision under these Terms shall not constitute a waiver of such right or provision. Except as otherwise provided herein, these Terms are intended solely for the benefit of DFlow and you and are not intended to confer third party beneficiary rights upon any other person or entity.
19. CONTACT INFORMATION
DFlow Inc.
ATTN: DFlow Legal
Email: [legal@dflow.net](mailto:legal@dflow.net)