Migrate from Jupiter to Carbium

Move a Jupiter Swap API integration onto Carbium by remapping quote parameters, replacing the separate swap-build step, and re-testing advanced execution options case by case.

Migrate from Jupiter to Carbium

If your current Solana trading flow is built around Jupiter Swap API, the migration is not "swap one hostname and keep the same request body."

Jupiter's documented flow is:

  1. request a quote
  2. send that full quoteResponse into a separate /swap request
  3. receive a base64 transaction

Carbium's published flow is different. Its current execution guide centers on a quote request that can already return the executable transaction when you include user_account.

That difference is the whole migration. This page shows what maps cleanly, what needs a rewrite, and which Jupiter-specific execution controls should be validated separately before cutover.

Part of the Carbium Solana infrastructure stack.

What maps cleanly

Jupiter surfaceCarbium surfaceMigration confidence
API-key authenticated quote requestAPI-key authenticated quote requestHigh
Quote request with input mint, output mint, amount, and slippageQuote request with source mint, destination mint, amount, and slippageHigh
Base64 transaction returned for client or backend signingBase64 txn returned when user_account is providedHigh
Sign and submit transaction with Solana SDK toolingSign and submit transaction through Carbium RPCHigh

For standard swap flows, the clean migration is to preserve the business logic around quote -> sign -> submit, while replacing the request shape and removing Jupiter's separate swap-build step.

What does not map 1:1

Do not port these blindly:

Jupiter capabilityCurrent Carbium docs statusWhat to do
Separate POST /swap transaction-build step using quoteResponseCarbium's current docs emphasize GET /api/v2/quote with user_account returning txn directlyRewrite the execution step instead of trying to preserve the same request choreography
dynamicComputeUnitLimit and dynamicSlippage in the documented Jupiter /swap bodyNo same-page Carbium equivalent is documented in the current execution guideRe-test landing behavior and keep Carbium execution settings explicit in your own code
Jupiter options like payer, wrapAndUnwrapSol, feeAccount, trackingAccount, and destination-account controlsNo direct one-to-one mapping is published in Carbium's current swap execution guideValidate each behavior individually before removing Jupiter from production
Jupiter's newer Swap V2 migration pathCarbium docs publish a different product surface rather than a Jupiter-shaped V2 cloneTreat this as a product migration, not a version bump

The mistake to avoid is carrying over a Jupiter-centric internal abstraction and assuming Carbium will accept the same quote object and execution settings. It will not.

Endpoint and parameter mapping

Quote request

Jupiter's current Swap docs publish a quote request like:

  • GET https://api.jup.ag/swap/v1/quote
  • header: x-api-key
  • query params such as inputMint, outputMint, amount, and slippageBps

Carbium's live execution guide publishes:

  • GET https://api.carbium.io/api/v2/quote
  • header: X-API-KEY
  • query params src_mint, dst_mint, amount_in, slippage_bps
  • user_account when you want the response to include an executable transaction
IntentJupiter paramCarbium param
Input tokeninputMintsrc_mint
Output tokenoutputMintdst_mint
Raw amountamountamount_in
Slippage in basis pointsslippageBpsslippage_bps
Wallet public key for executable transactionpassed later as userPublicKey to /swappassed now as user_account to /quote

Execution step

Jupiter's documented flow builds the executable transaction in a second request:

POST /swap
{
  "userPublicKey": "...",
  "quoteResponse": { "...": "..." }
}

Carbium's current guide collapses that into the quote call. When user_account is included, the quote response contains txn, a base64-encoded VersionedTransaction ready for signing.

That means the migration usually looks like this:

  1. stop passing a Jupiter quoteResponse into a second swap-builder request
  2. request the Carbium quote with user_account
  3. deserialize txn
  4. sign it
  5. submit it through Carbium RPC

Minimal rewrite example

Before: Jupiter-style flow

const quoteUrl = new URL("https://api.jup.ag/swap/v1/quote");
quoteUrl.searchParams.set("inputMint", inputMint);
quoteUrl.searchParams.set("outputMint", outputMint);
quoteUrl.searchParams.set("amount", amountIn);
quoteUrl.searchParams.set("slippageBps", "50");

const quoteResponse = await fetch(quoteUrl, {
  headers: { "x-api-key": process.env.JUP_API_KEY! },
}).then((r) => r.json());

const swapResponse = await fetch("https://api.jup.ag/swap/v1/swap", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": process.env.JUP_API_KEY!,
  },
  body: JSON.stringify({
    userPublicKey: wallet.publicKey.toBase58(),
    quoteResponse,
  }),
}).then((r) => r.json());

After: Carbium-style flow

const quoteUrl = new URL("https://api.carbium.io/api/v2/quote");
quoteUrl.searchParams.set("src_mint", inputMint);
quoteUrl.searchParams.set("dst_mint", outputMint);
quoteUrl.searchParams.set("amount_in", amountIn);
quoteUrl.searchParams.set("slippage_bps", "50");
quoteUrl.searchParams.set("user_account", wallet.publicKey.toBase58());

const quote = await fetch(quoteUrl, {
  headers: { "X-API-KEY": process.env.CARBIUM_API_KEY! },
}).then((r) => r.json());

if (!quote.txn) {
  throw new Error("Missing executable transaction in Carbium quote response");
}

const transaction = VersionedTransaction.deserialize(
  Buffer.from(quote.txn, "base64")
);

transaction.sign([wallet]);

const connection = new Connection(
  `https://rpc.carbium.io/?apiKey=${process.env.CARBIUM_RPC_KEY}`,
  "confirmed"
);

const signature = await connection.sendTransaction(transaction, {
  skipPreflight: true,
  maxRetries: 3,
});

Safe cutover sequence

Use this order for production migrations:

  1. Inventory whether your Jupiter integration only uses quote and swap, or whether it also depends on custom payer, fee collection, dynamic slippage, or destination-account controls.
  2. Create separate CARBIUM_API_KEY and CARBIUM_RPC_KEY secrets.
  3. Rewrite the quote request shape first.
  4. Replace the Jupiter /swap step with Carbium quote deserialization and RPC submission.
  5. Re-test confirmation, retry logic, and slippage handling under live market conditions.
  6. Validate any Jupiter-only advanced execution settings individually before removing the old path.

This keeps the migration narrow. Core swap execution can move first, while fee-routing or account-management edge cases stay isolated until verified.

Migration checklist

  • CARBIUM_API_KEY exists in your secret store
  • CARBIUM_RPC_KEY exists for transaction submission
  • Jupiter quote parameters are translated to Carbium's src_mint, dst_mint, amount_in, and slippage_bps
  • The execution path no longer assumes a separate Jupiter /swap request
  • user_account is included on Carbium quote requests that need an executable transaction
  • Signed transactions are submitted through Carbium RPC and confirmed before replay
  • Any Jupiter-specific payer, fee, or destination-account options have been re-tested explicitly

When Carbium is a good fit

Carbium is the cleanest next step when your current Jupiter integration is mainly:

  • quote -> transaction -> sign -> submit
  • backend-safe API-key usage
  • wallet, bot, or app flows that can work with an executable transaction returned from the quote layer

It is not a one-line migration if your current integration depends heavily on Jupiter-specific execution controls that Carbium's public docs do not currently mirror on the same surface.

📘Treat this as a flow migration, not a field rename. The biggest change is architectural: Carbium's published guide returns txn from the quote step when you pass user_account.
🔶Ready to move your swap flow off Jupiter? Start with Carbium API setup at carbium.io and validate the rewritten quote path before production cutover.