Migrate from Jupiter to Carbium

Move a Jupiter-centered Solana swap integration to Carbium by mapping quote parameters, signing boundaries, execution ownership, and rollback checks.

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."

Start by identifying which Jupiter surface your code depends on:

  • legacy Metis-style quote and swap flows
  • Ultra order and execute flows
  • newer Swap API flows with managed execution or custom transaction paths
  • token, price, trigger, recurring, or lending APIs that are not simple swaps

Carbium's published flow is narrower and more direct. The current public Swap API path 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 product surfaces should stay separate until they have their own migration plan.

Part of the Carbium Solana infrastructure stack.


What changes in the migration

The main difference is execution ownership.

Jupiter's current developer docs present API families where Jupiter can handle more of the swap lifecycle, including order creation, execution, landing infrastructure, token services, and adjacent DeFi APIs. Jupiter also now points older Metis and Ultra flows toward newer Swap API migration paths.

Carbium's public docs focus the swap path around GET https://api.carbium.io/api/v2/quote, which can return a base64 txn when user_account is provided.

That makes the migration straightforward for quote-to-transaction builders, but not a 1:1 replacement for every Jupiter product surface.

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
Jupiter-managed execute or landing flowApp-owned signing, submission, and confirmationMedium
Jupiter token, price, trigger, recurring, lending, or limit-order APIsNo documented Carbium drop-in replacement in current public docsLow

For standard swap flows, the clean migration is to preserve the business logic around quote -> sign -> submit while replacing the request shape and removing provider-specific objects from the flow.

What does not map 1:1

Do not port these blindly:

Jupiter capabilityCurrent Carbium docs statusWhat to do
Legacy Metis quoteResponse passed into a separate transaction-build requestCarbium'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
Ultra-style order and execute flowsNo Carbium-managed execute equivalent is documented in the current public swap guidesTreat this as an ownership change and prove app-owned submission before cutover
Jupiter options like custom payer, fee, destination-account, dynamic slippage, route filters, or transaction-size controlsNo direct one-to-one mapping is published in Carbium's current Q1 guideValidate each behavior individually before removing Jupiter from production
Token, price, trigger, recurring, lending, or limit-order APIsOutside the current Carbium Swap API migration pathKeep them on Jupiter or assign a separate replacement owner

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.

📘

Migrate the plain swap path first. Keep non-swap Jupiter APIs on a separate workstream until you have a tested Carbium replacement or decide to keep them hybrid.


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

Many legacy Jupiter integrations build 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: legacy 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 managed execution, custom payer, fee collection, token metadata, price feeds, recurring orders, or limit-order controls.
  2. Create separate CARBIUM_API_KEY and CARBIUM_RPC_KEY secrets.
  3. Rewrite the quote request shape first.
  4. Replace provider-specific transaction-build or execute steps 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 Jupiter-specific quoteResponse, order, or execute object
  • 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, destination-account, token, price, or order features have been re-tested explicitly or left hybrid

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 Q1 for the request shape, then use the Quote to Swap Integration Guide once the returned txn is stable.