Skip to main content
During development, you can use the developer endpoints without an API key. For production use, you’ll need an API key to avoid rate limits.
Use 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.
1

Request an Intent Quote

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.
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();
2

Sign the Intent

Sign the intent, guaranteeing the minimum amount of output tokens without committing to any given route plan.
const transaction = intentData.openTransaction;
const transactionBytes = Buffer.from(transaction, "base64");
const openTransaction = Transaction.from(transactionBytes);

openTransaction.sign(keypair);
3

Submit the Intent

Intents are submitted to the DFlow Aggregator, which optimizes the execution of the trade based on network conditions.
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();
4

Monitor the Intent

After submitting the Intent, monitor its status using the monitorOrder helper function from the @dflow-protocol/swap-api-utils package.
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

Cookbook Repository

This recipe, along with many more, is available in the DFlow Cookbook Repo. You can clone it and start coding immediately.