# Table of Contents - [Introduction | JupiterZ Documentation](#introduction-jupiterz-documentation) - [Integrator Overview | JupiterZ Documentation](#integrator-overview-jupiterz-documentation) - [JupiterZ API | JupiterZ Documentation](#jupiterz-api-jupiterz-documentation) - [JupiterZ v2 | JupiterZ Documentation](#jupiterz-v2-jupiterz-documentation) - [API Overview | JupiterZ Documentation](#api-overview-jupiterz-documentation) - [Integration Overview | JupiterZ Documentation](#integration-overview-jupiterz-documentation) - [Execute Endpoint | JupiterZ Documentation](#execute-endpoint-jupiterz-documentation) - [Order Endpoints | JupiterZ Documentation](#order-endpoints-jupiterz-documentation) - [Testing Overview | JupiterZ Documentation](#testing-overview-jupiterz-documentation) - [Frequently Asked Questions | JupiterZ Documentation](#frequently-asked-questions-jupiterz-documentation) --- # Introduction | JupiterZ Documentation [Skip to main content](https://jupiterz.jup.ag/docs/intro#__docusaurus_skipToContent_fallback) On this page Welcome to the **JupiterZ Webhook Toolkit** documentation! This comprehensive guide will help you integrate your market making system with Jupiter's Request for Quote (RFQ) module. What is JupiterZ?[​](https://jupiterz.jup.ag/docs/intro#what-is-jupiterz "Direct link to What is JupiterZ?") ------------------------------------------------------------------------------------------------------------- JupiterZ allows market makers to provide liquidity and adjust their quotes without being subject to the volatility of on-chain gas prices or chain health. RFQ fills are much less computationally intensive (10x less) compared to AMM swaps and can save gas costs in the long run. info 📣 **NOTE**: This integration is still subject to changes, and we welcome suggestions for improvements. If you're interested in becoming a Market Maker on JupiterZ, please read this documentation and reach out to [dexterdev8](https://t.me/dexterdev8) on Telegram to register your webhook. Key Features[​](https://jupiterz.jup.ag/docs/intro#key-features "Direct link to Key Features") ----------------------------------------------------------------------------------------------- * **Low Computational Cost**: RFQ fills are 10x less CU intensive than AMM swaps * **Gas Optimization**: Save on transaction costs compared to traditional AMM routes * **Dynamic Pricing**: Adjust quotes without on-chain volatility concerns * **Flexible Integration**: RESTful webhook API for easy integration Getting Started[​](https://jupiterz.jup.ag/docs/intro#getting-started "Direct link to Getting Started") -------------------------------------------------------------------------------------------------------- Choose your path based on your role: * **Market Makers**: Start with the [Integration Guide](https://jupiterz.jup.ag/docs/integration/overview) to understand the webhook requirements * **Integrators**: Consuming JupiterZ quotes in your app? See the [Integrator docs](https://jupiterz.jup.ag/docs/integrators/overview) * **Developers**: Check out the [API Documentation](https://jupiterz.jup.ag/docs/api/overview) for technical details * **Testing**: Use our [Testing Suite](https://jupiterz.jup.ag/docs/testing/overview) to validate your implementation Integration Overview[​](https://jupiterz.jup.ag/docs/intro#integration-overview "Direct link to Integration Overview") ----------------------------------------------------------------------------------------------------------------------- The RFQ system works through a webhook-based architecture where: 1. **Registration**: Market makers register their webhook endpoints with Jupiter 2. **Quote Requests**: Jupiter sends quote requests to registered webhooks 3. **Quote Response**: Webhooks respond with competitive quotes within 250ms 4. **Swap Execution**: Users can execute swaps using the best available quotes Quick Links[​](https://jupiterz.jup.ag/docs/intro#quick-links "Direct link to Quick Links") -------------------------------------------------------------------------------------------- * [Order Engine Program](https://solscan.io/account/61DFfeTKM7trxYcPQCM78bJ794ddZprZpAwAnLiwTpYH) (Mainnet) * [GitHub Repository](https://github.com/jup-ag/rfq-webhook-toolkit) * [OpenAPI Documentation](https://github.com/jup-ag/rfq-webhook-toolkit/blob/main/openapi) * [Audit Report](https://github.com/jup-ag/rfq-webhook-toolkit/blob/main/audits/Jupiter-RFQ-Nov-2024-OffsideLabs.pdf) by Offside Labs Need Help?[​](https://jupiterz.jup.ag/docs/intro#need-help "Direct link to Need Help?") ---------------------------------------------------------------------------------------- * Check the [FAQ](https://jupiterz.jup.ag/docs/faq) for common questions * Review the [Troubleshooting](https://jupiterz.jup.ag/docs/testing/troubleshooting) guide for common issues * Reach out on [Telegram](https://t.me/dexterdev8) for direct support * [What is JupiterZ?](https://jupiterz.jup.ag/docs/intro#what-is-jupiterz) * [Key Features](https://jupiterz.jup.ag/docs/intro#key-features) * [Getting Started](https://jupiterz.jup.ag/docs/intro#getting-started) * [Integration Overview](https://jupiterz.jup.ag/docs/intro#integration-overview) * [Quick Links](https://jupiterz.jup.ag/docs/intro#quick-links) * [Need Help?](https://jupiterz.jup.ag/docs/intro#need-help) --- # Integrator Overview | JupiterZ Documentation [Skip to main content](https://jupiterz.jup.ag/docs/integrators/overview#__docusaurus_skipToContent_fallback) On this page The JupiterZ API lets you source RFQ liquidity directly: request a quote from Jupiter's market makers, have the user sign the returned transaction, and send it back for execution. Unlike the [Market Maker docs](https://jupiterz.jup.ag/docs/intro) , this section is for **integrators consuming quotes** — wallets, aggregators, trading UIs and bots. Access JupiterZ is available as a standalone API through the **[Jupiter Develop Platform](https://developers.jup.ag/) **. Create an account there to get an API key. Base URL[​](https://jupiterz.jup.ag/docs/integrators/overview#base-url "Direct link to Base URL") -------------------------------------------------------------------------------------------------- https://api.jup.ag/swap/v2/jupiterz Authentication[​](https://jupiterz.jup.ag/docs/integrators/overview#authentication "Direct link to Authentication") -------------------------------------------------------------------------------------------------------------------- Every request must carry your API key: x-api-key: your-api-key Requests without it return `401 Unauthorized`. Endpoints[​](https://jupiterz.jup.ag/docs/integrators/overview#endpoints "Direct link to Endpoints") ----------------------------------------------------------------------------------------------------- | Endpoint | Method | Purpose | | --- | --- | --- | | [`/order`](https://jupiterz.jup.ag/docs/integrators/order) | `GET` | Best quote for a single token pair | | [`/global-order`](https://jupiterz.jup.ag/docs/integrators/order#global-order) | `GET` | Best quote across up to 5 candidate output mints | | [`/execute`](https://jupiterz.jup.ag/docs/integrators/execute) | `POST` | Submit the signed transaction for execution | How it works[​](https://jupiterz.jup.ag/docs/integrators/overview#how-it-works "Direct link to How it works") -------------------------------------------------------------------------------------------------------------- Market MakersJupiterZYour AppUserMarket MakersJupiterZYour AppUserGET /orderRequest quotesQuotesBest quote + unsigned transactionSign transactionPartially signed transactionPOST /executeMaker co-signs and submitsSignature + state The transaction returned by `/order` is a **base64-encoded versioned transaction**. The taker signs it (partial signature); the market maker adds the final signature and submits it on-chain. You never build or submit the transaction yourself. Quickstart[​](https://jupiterz.jup.ag/docs/integrators/overview#quickstart "Direct link to Quickstart") -------------------------------------------------------------------------------------------------------- import { VersionedTransaction } from '@solana/web3.js';const BASE = 'https://api.jup.ag/swap/v2/jupiterz';const headers = { 'x-api-key': process.env.JUP_API_KEY! };// 1. Get a quoteconst params = new URLSearchParams({ inputMint: 'So11111111111111111111111111111111111111112', // SOL outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC amount: '1000000000', // 1 SOL taker: takerPublicKey.toBase58(), swapMode: 'ExactIn',});const order = await fetch(`${BASE}/order?${params}`, { headers }).then(r => r.json());// 2. Sign itconst tx = VersionedTransaction.deserialize( Buffer.from(order.transaction, 'base64'),);tx.sign([takerKeypair]);// 3. Executeconst result = await fetch(`${BASE}/execute`, { method: 'POST', headers: { ...headers, 'Content-Type': 'application/json' }, body: JSON.stringify({ requestId: order.requestId, quoteId: order.quoteId, transaction: Buffer.from(tx.serialize()).toString('base64'), }),}).then(r => r.json());console.log(result.state, result.signature); Amounts[​](https://jupiterz.jup.ag/docs/integrators/overview#amounts "Direct link to Amounts") ----------------------------------------------------------------------------------------------- All amounts are **strings in the token's smallest unit**, so no precision is lost: { "amount": "1000000", // 1 USDC (6 decimals) "amount": "1000000000" // 1 SOL (9 decimals)} Errors[​](https://jupiterz.jup.ag/docs/integrators/overview#errors "Direct link to Errors") -------------------------------------------------------------------------------------------- Errors use a consistent JSON body: { "error": "No quote found", "errorCode": "NO_QUOTE_FOUND"} `error` is always present. `errorCode` is `null` unless the failure maps to one of the codes below. | Status | Meaning | | --- | --- | | `400 Bad Request` | Invalid or missing parameters, expired quote, failed simulation | | `401 Unauthorized` | Missing or invalid `x-api-key` | | `404 Not Found` | No market maker quoted this pair | | `429 Too Many Requests` | Rate limit exceeded | | `500 Internal Server Error` | Server-side failure | ### Error codes[​](https://jupiterz.jup.ag/docs/integrators/overview#error-codes "Direct link to Error codes") | Code | Meaning | | --- | --- | | `NO_QUOTE_FOUND` | No market maker returned a quote for this request | | `QUOTE_EXPIRED` | The quote expired before `/execute` was called | | `0x1` | Taker has insufficient funds | | `0xbc4` | A required token account is missing | | `0x11` | Token account is frozen | | `SIMULATION_FAILED` | The swap could not be simulated | | `TRANSACTION_ERROR` | Transaction-level failure during simulation | | `INSTRUCTION_ERROR` | Instruction-level failure during simulation | Next steps[​](https://jupiterz.jup.ag/docs/integrators/overview#next-steps "Direct link to Next steps") -------------------------------------------------------------------------------------------------------- * **[Order Endpoints](https://jupiterz.jup.ag/docs/integrators/order) ** — request a quote * **[Execute Endpoint](https://jupiterz.jup.ag/docs/integrators/execute) ** — execute a signed quote * [Base URL](https://jupiterz.jup.ag/docs/integrators/overview#base-url) * [Authentication](https://jupiterz.jup.ag/docs/integrators/overview#authentication) * [Endpoints](https://jupiterz.jup.ag/docs/integrators/overview#endpoints) * [How it works](https://jupiterz.jup.ag/docs/integrators/overview#how-it-works) * [Quickstart](https://jupiterz.jup.ag/docs/integrators/overview#quickstart) * [Amounts](https://jupiterz.jup.ag/docs/integrators/overview#amounts) * [Errors](https://jupiterz.jup.ag/docs/integrators/overview#errors) * [Error codes](https://jupiterz.jup.ag/docs/integrators/overview#error-codes) * [Next steps](https://jupiterz.jup.ag/docs/integrators/overview#next-steps) --- # JupiterZ API | JupiterZ Documentation [Skip to main content](https://jupiterz.jup.ag/docs/stats/overview#__docusaurus_skipToContent_fallback) The JupiterZ API documentation is being rewritten and is temporarily unavailable. In the meantime: * **Integrating JupiterZ into your app?** See the [Integrator docs](https://jupiterz.jup.ag/docs/integrators/overview) . * **Running a market maker?** See the [Market Maker docs](https://jupiterz.jup.ag/docs/intro) . For anything else, reach out on [Telegram](https://t.me/dexterdev8) . --- # JupiterZ v2 | JupiterZ Documentation [Skip to main content](https://jupiterz.jup.ag/docs/v2#__docusaurus_skipToContent_fallback) On this page **JupiterZ v2** (internally, **RFQ v2**) is Jupiter's streaming Request-for-Quote system for market makers on Solana. Market makers connect over **gRPC**, continuously stream priced orderbooks, and settle user swaps on-chain through Jupiter's Order Engine program — reviewing and co-signing each fill (**last look**) before it lands. This section is the integration reference for market makers. It is written against the shipped code in the [`rfq-v2-sdk`](https://github.com/jup-ag/rfq-v2-sdk) (Rust and Python SDKs) and the `market-maker-ingestion-service` that your SDK connects to. JupiterZ vs RFQ v2 "JupiterZ" is the product/consumer brand; "RFQ v2" is the technical name for the same system. This documentation uses **RFQ v2** when talking about the protocol and SDKs. Two generations, side by side[​](https://jupiterz.jup.ag/docs/v2#two-generations-side-by-side "Direct link to Two generations, side by side") ---------------------------------------------------------------------------------------------------------------------------------------------- V2 does not replace V1 — they run concurrently, and you can integrate with either or both. | | V1 (webhook) | V2 (streaming) | | --- | --- | --- | | Transport | HTTP webhooks (Jupiter calls you per request) | Persistent **bidirectional gRPC** streams (you push continuously) | | Quoting | Cold start on every request; respond within a deadline | Quotes served from an **in-memory orderbook cache**; you set your own cadence | | Quote ↔ swap | Same webhook for both | **Decoupled**: a quote stream and a separate swap stream | | Pricing model | Compute per request | Stream multi-level orderbooks (bids/asks) ahead of time | | Settlement | Order Engine program (on-chain) | **Same** Order Engine program (unchanged) | The [V1 webhook documentation](https://jupiterz.jup.ag/docs/intro) covers the webhook flow. The rest of this section is V2 only. Documentation map[​](https://jupiterz.jup.ag/docs/v2#documentation-map "Direct link to Documentation map") ----------------------------------------------------------------------------------------------------------- * **[Overview](https://jupiterz.jup.ag/docs/v2/overview) ** — what RFQ v2 is, the streaming model, and what you need to integrate. * **[Getting Started](https://jupiterz.jup.ag/docs/v2/getting-started) ** — credentials, installing the Rust or Python SDK, and your first connection. * **[SDK Integration](https://jupiterz.jup.ag/docs/v2/sdk-integration) ** — the full quoting and swap loop with the official SDKs. * **[Last Look & Maker Safety](https://jupiterz.jup.ag/docs/v2/last-look-and-safety) ** — validating and co-signing fills, and the on-chain guards that protect your funds. * **[gRPC API Reference](https://jupiterz.jup.ag/docs/v2/grpc-api) ** — the protobuf contract, encoding rules, authentication, and server-side validation. * **[Testing](https://jupiterz.jup.ag/docs/v2/testing) ** — the SDK end-to-end suite, unit tests, and the pre-production checklist. Architecture[​](https://jupiterz.jup.ag/docs/v2#architecture "Direct link to Architecture") -------------------------------------------------------------------------------------------- A market maker keeps two long-lived gRPC streams open to the ingestion service. Quotes flow into an in-memory orderbook cache that Jupiter's quote layer reads when a user asks for a price; when the user signs, the swap is pushed back to the market maker for last look. Loading chunk 3624 failed. (error: https://jupiterz.jup.ag/assets/js/3624.04a0c515.js) Try again _The two market-maker streams (quotes in, swaps out) run to the ingestion service, which caches orderbooks for Jupiter's quote layer and settles co-signed fills on-chain. The step-by-step ordering is in the [end-to-end flow](https://jupiterz.jup.ag/docs/v2#end-to-end-flow) below._ ### End-to-end flow[​](https://jupiterz.jup.ag/docs/v2#end-to-end-flow "Direct link to End-to-end flow") Loading chunk 5831 failed. (error: https://jupiterz.jup.ag/assets/js/5831.1a2daf4b.js) Try again The swap stream must be open before you quote The ingestion service **rejects every quote** from a maker that does not have a live `StreamSwap` connection. Open your swap stream first, then start quoting. See [SDK Integration](https://jupiterz.jup.ag/docs/v2/sdk-integration#connect-both-streams) . Next steps[​](https://jupiterz.jup.ag/docs/v2#next-steps "Direct link to Next steps") -------------------------------------------------------------------------------------- Start with the **[Overview](https://jupiterz.jup.ag/docs/v2/overview) ** to understand the model, then follow **[Getting Started](https://jupiterz.jup.ag/docs/v2/getting-started) ** to connect. * [Two generations, side by side](https://jupiterz.jup.ag/docs/v2#two-generations-side-by-side) * [Documentation map](https://jupiterz.jup.ag/docs/v2#documentation-map) * [Architecture](https://jupiterz.jup.ag/docs/v2#architecture) * [End-to-end flow](https://jupiterz.jup.ag/docs/v2#end-to-end-flow) * [Next steps](https://jupiterz.jup.ag/docs/v2#next-steps) --- # API Overview | JupiterZ Documentation [Skip to main content](https://jupiterz.jup.ag/docs/api/overview#__docusaurus_skipToContent_fallback) On this page The JupiterZ Webhook API consists of three main endpoints that your webhook must implement. This section provides detailed specifications for each endpoint. Base Requirements[​](https://jupiterz.jup.ag/docs/api/overview#base-requirements "Direct link to Base Requirements") --------------------------------------------------------------------------------------------------------------------- ### Endpoint Structure[​](https://jupiterz.jup.ag/docs/api/overview#endpoint-structure "Direct link to Endpoint Structure") Your webhook will be registered with a base URL, and Jupiter will append specific paths: Base URL: https://your-api-endpoint.com/jupiter/rfq Required endpoints: * `GET {baseUrl}/tokens` - Token support advertisement * `POST {baseUrl}/quote` - Quote generation * `POST {baseUrl}/swap` - Swap execution Optional endpoints: * `GET {baseUrl}/permissioned-tokens` - Tokens filled just-in-time with a mint/burn ### Authentication[​](https://jupiterz.jup.ag/docs/api/overview#authentication "Direct link to Authentication") If your webhook requires authentication, provide an API key during registration. Jupiter will include it in requests as: X-API-KEY: your-provided-api-key ### Content Type[​](https://jupiterz.jup.ag/docs/api/overview#content-type "Direct link to Content Type") All requests and responses use `application/json` content type. ### Timeout Requirements[​](https://jupiterz.jup.ag/docs/api/overview#timeout-requirements "Direct link to Timeout Requirements") * **Quote requests**: 250ms maximum response time * **Swap requests**: 25 seconds maximum response time Request Headers[​](https://jupiterz.jup.ag/docs/api/overview#request-headers "Direct link to Request Headers") --------------------------------------------------------------------------------------------------------------- Jupiter includes these headers in all requests: | Header | Description | | --- | --- | | `Content-Type` | `application/json` | | `X-API-KEY` | Your API key (if provided during registration) | | `x-request-start` | Millisecond timestamp when request was sent | | `x-request-timeout` | Request timeout in milliseconds (250ms for quotes) | HTTP Status Codes[​](https://jupiterz.jup.ag/docs/api/overview#http-status-codes "Direct link to HTTP Status Codes") --------------------------------------------------------------------------------------------------------------------- ### Successful Responses[​](https://jupiterz.jup.ag/docs/api/overview#successful-responses "Direct link to Successful Responses") * **`200 OK`** - Request successful, returning data * **`404 Not Found`** - No quote available for this request ### Error Responses[​](https://jupiterz.jup.ag/docs/api/overview#error-responses "Direct link to Error Responses") * **`400 Bad Request`** - Malformed request parameters * **`401 Unauthorized`** - Missing or invalid API key * **`429 Too Many Requests`** - Rate limit exceeded * **`500 Internal Server Error`** - Server error occurred * **`503 Service Unavailable`** - Temporarily unable to serve requests Performance Requirements Webhooks that consistently return 5xx errors or fail to respond within timeout limits will be temporarily suspended from receiving requests. Data Types and Formats[​](https://jupiterz.jup.ag/docs/api/overview#data-types-and-formats "Direct link to Data Types and Formats") ------------------------------------------------------------------------------------------------------------------------------------ ### Token Addresses[​](https://jupiterz.jup.ag/docs/api/overview#token-addresses "Direct link to Token Addresses") All token addresses are base58-encoded Solana public keys: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" // USDC"So11111111111111111111111111111111111111112" // SOL (Native) ### Amount Representation[​](https://jupiterz.jup.ag/docs/api/overview#amount-representation "Direct link to Amount Representation") All token amounts are represented as strings in their smallest unit (considering token decimals): { "amount": "1000000", // 1 USDC (6 decimals) "amount": "1000000000" // 1 SOL (9 decimals)} ### Swap Modes[​](https://jupiterz.jup.ag/docs/api/overview#swap-modes "Direct link to Swap Modes") * **`ExactIn`** - Exact input amount, variable output * **`ExactOut`** - Variable input amount, exact output Validation Requirements[​](https://jupiterz.jup.ag/docs/api/overview#validation-requirements "Direct link to Validation Requirements") --------------------------------------------------------------------------------------------------------------------------------------- ### Input Validation[​](https://jupiterz.jup.ag/docs/api/overview#input-validation "Direct link to Input Validation") Always validate incoming requests: * Token addresses are valid base58 Solana public keys * Amounts are positive integers * Swap modes are valid enum values * Required fields are present ### Output Validation[​](https://jupiterz.jup.ag/docs/api/overview#output-validation "Direct link to Output Validation") Ensure your responses match the expected format: * All required fields are present * Data types match specifications * Amounts are properly formatted * Price impacts are reasonable OpenAPI Specification[​](https://jupiterz.jup.ag/docs/api/overview#openapi-specification "Direct link to OpenAPI Specification") --------------------------------------------------------------------------------------------------------------------------------- Complete OpenAPI documentation is available in the [GitHub repository](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/openapi) . You can also run the sample server to explore the interactive documentation: make run-server-example# Visit http://localhost:8080/swagger-ui/ Next Steps[​](https://jupiterz.jup.ag/docs/api/overview#next-steps "Direct link to Next Steps") ------------------------------------------------------------------------------------------------ Explore the detailed endpoint specifications: * **[Tokens Endpoint](https://jupiterz.jup.ag/docs/api/tokens) ** - Token support advertisement * **[Quote Endpoint](https://jupiterz.jup.ag/docs/api/quote) ** - Quote request/response format * **[Swap Endpoint](https://jupiterz.jup.ag/docs/api/swap) ** - Swap execution details * [Base Requirements](https://jupiterz.jup.ag/docs/api/overview#base-requirements) * [Endpoint Structure](https://jupiterz.jup.ag/docs/api/overview#endpoint-structure) * [Authentication](https://jupiterz.jup.ag/docs/api/overview#authentication) * [Content Type](https://jupiterz.jup.ag/docs/api/overview#content-type) * [Timeout Requirements](https://jupiterz.jup.ag/docs/api/overview#timeout-requirements) * [Request Headers](https://jupiterz.jup.ag/docs/api/overview#request-headers) * [HTTP Status Codes](https://jupiterz.jup.ag/docs/api/overview#http-status-codes) * [Successful Responses](https://jupiterz.jup.ag/docs/api/overview#successful-responses) * [Error Responses](https://jupiterz.jup.ag/docs/api/overview#error-responses) * [Data Types and Formats](https://jupiterz.jup.ag/docs/api/overview#data-types-and-formats) * [Token Addresses](https://jupiterz.jup.ag/docs/api/overview#token-addresses) * [Amount Representation](https://jupiterz.jup.ag/docs/api/overview#amount-representation) * [Swap Modes](https://jupiterz.jup.ag/docs/api/overview#swap-modes) * [Validation Requirements](https://jupiterz.jup.ag/docs/api/overview#validation-requirements) * [Input Validation](https://jupiterz.jup.ag/docs/api/overview#input-validation) * [Output Validation](https://jupiterz.jup.ag/docs/api/overview#output-validation) * [OpenAPI Specification](https://jupiterz.jup.ag/docs/api/overview#openapi-specification) * [Next Steps](https://jupiterz.jup.ag/docs/api/overview#next-steps) --- # Integration Overview | JupiterZ Documentation [Skip to main content](https://jupiterz.jup.ag/docs/integration/overview#__docusaurus_skipToContent_fallback) On this page This section provides comprehensive guidance for market makers looking to integrate with Jupiter's RFQ system. The integration involves setting up webhook endpoints that can handle quote requests and swap executions. Architecture Overview[​](https://jupiterz.jup.ag/docs/integration/overview#architecture-overview "Direct link to Architecture Overview") ----------------------------------------------------------------------------------------------------------------------------------------- The following diagram illustrates the request workflow: SolanaWebhookJupiterUserSolanaWebhookJupiterUserRequest QuotePOST /quoteQuote ResponseBest QuoteExecute SwapPOST /swapSubmit TransactionTransaction Confirmed Webhook Endpoints[​](https://jupiterz.jup.ag/docs/integration/overview#webhook-endpoints "Direct link to Webhook Endpoints") ----------------------------------------------------------------------------------------------------------------------------- Your webhook must implement three main endpoints: ### Required Endpoints[​](https://jupiterz.jup.ag/docs/integration/overview#required-endpoints "Direct link to Required Endpoints") * **`GET /tokens`** - List supported token pairs * **`POST /quote`** - Provide quotes for token swaps * **`POST /swap`** - Execute verified swaps ### Base URL Registration[​](https://jupiterz.jup.ag/docs/integration/overview#base-url-registration "Direct link to Base URL Registration") When registering with Jupiter, you'll provide a base URL like: https://your-api-endpoint.com/jupiter/rfq Jupiter will then call: * `GET https://your-api-endpoint.com/jupiter/rfq/tokens` * `POST https://your-api-endpoint.com/jupiter/rfq/quote` * `POST https://your-api-endpoint.com/jupiter/rfq/swap` Key Requirements[​](https://jupiterz.jup.ag/docs/integration/overview#key-requirements "Direct link to Key Requirements") -------------------------------------------------------------------------------------------------------------------------- ### Response Time[​](https://jupiterz.jup.ag/docs/integration/overview#response-time "Direct link to Response Time") * **Quote requests**: Must respond within **250ms** ### Fulfillment Rate[​](https://jupiterz.jup.ag/docs/integration/overview#fulfillment-rate "Direct link to Fulfillment Rate") * Market makers must maintain a **95% fulfillment rate** * Falling below 95% in a 1 minute window will result in temporary suspension ### API Authentication[​](https://jupiterz.jup.ag/docs/integration/overview#api-authentication "Direct link to API Authentication") If your webhook requires authentication, provide an API key during registration. Jupiter will include it as the `X-API-KEY` header in all requests. Next Steps[​](https://jupiterz.jup.ag/docs/integration/overview#next-steps "Direct link to Next Steps") -------------------------------------------------------------------------------------------------------- 1. **[Webhook Implementation](https://jupiterz.jup.ag/docs/integration/webhook-implementation) ** - Learn how to build your webhook endpoints 2. **[API Specifications](https://jupiterz.jup.ag/docs/api/overview) ** - Detailed API documentation 3. **[Testing](https://jupiterz.jup.ag/docs/testing/overview) ** - Validate your implementation 4. **[Deployment](https://jupiterz.jup.ag/docs/integration/deployment) ** - Production deployment guidelines * [Architecture Overview](https://jupiterz.jup.ag/docs/integration/overview#architecture-overview) * [Webhook Endpoints](https://jupiterz.jup.ag/docs/integration/overview#webhook-endpoints) * [Required Endpoints](https://jupiterz.jup.ag/docs/integration/overview#required-endpoints) * [Base URL Registration](https://jupiterz.jup.ag/docs/integration/overview#base-url-registration) * [Key Requirements](https://jupiterz.jup.ag/docs/integration/overview#key-requirements) * [Response Time](https://jupiterz.jup.ag/docs/integration/overview#response-time) * [Fulfillment Rate](https://jupiterz.jup.ag/docs/integration/overview#fulfillment-rate) * [API Authentication](https://jupiterz.jup.ag/docs/integration/overview#api-authentication) * [Next Steps](https://jupiterz.jup.ag/docs/integration/overview#next-steps) --- # Execute Endpoint | JupiterZ Documentation [Skip to main content](https://jupiterz.jup.ag/docs/integrators/execute#__docusaurus_skipToContent_fallback) On this page `/execute` takes the transaction from [`/order`](https://jupiterz.jup.ag/docs/integrators/order) — now signed by the taker — and hands it to the market maker, who adds the final signature and submits it to Solana. **Method:** `POST` **URL:** `https://api.jup.ag/swap/v2/jupiterz/execute` Request[​](https://jupiterz.jup.ag/docs/integrators/execute#request "Direct link to Request") ---------------------------------------------------------------------------------------------- curl -X POST 'https://api.jup.ag/swap/v2/jupiterz/execute' \ -H 'x-api-key: your-api-key' \ -H 'Content-Type: application/json' \ -d '{ "requestId": "629bddf3-0038-43a6-8956-f5433d6b1191", "quoteId": "59db3e19-c7b0-4753-a8aa-206701004498", "transaction": "AgAAAAAAAAAA..." }' | Field | Type | Required | Description | | --- | --- | --- | --- | | `requestId` | string | Yes | `requestId` from the order response, unchanged | | `quoteId` | string | Yes | `quoteId` from the order response, unchanged | | `transaction` | string | Yes | The order's `transaction`, signed by the taker and re-encoded as base64 | Sign the transaction as-is. Rebuilding it, reordering instructions or changing amounts invalidates it — the market maker verifies the transaction it originally quoted before signing. Response[​](https://jupiterz.jup.ag/docs/integrators/execute#response "Direct link to Response") ------------------------------------------------------------------------------------------------- { "quoteId": "59db3e19-c7b0-4753-a8aa-206701004498", "state": "confirmed", "signature": "5h7...Xk2"} | Field | Type | Description | | --- | --- | --- | | `quoteId` | string | Echo of the quote ID | | `state` | string | Outcome of the swap. See below | | `signature` | string \| null | Transaction signature, once the fill is known | ### States[​](https://jupiterz.jup.ag/docs/integrators/execute#states "Direct link to States") | State | `signature` | Meaning | | --- | --- | --- | | `confirmed` | Present | The swap landed on-chain. Terminal | | `accepted` | `null` | The market maker accepted and submitted the swap, but on-chain confirmation is still pending | | `rejected` | `null` | The market maker declined to fill | | `invalid` | `null` | The transaction did not pass validation | | `failed` | `null` | Network error or timeout reaching the market maker | note A rejected or failed swap still returns `200 OK` with the state in the body — check `state`, not just the HTTP status. ### Pending confirmations[​](https://jupiterz.jup.ag/docs/integrators/execute#pending-confirmations "Direct link to Pending confirmations") An `accepted` response means the transaction was submitted but not yet seen as confirmed. Calling `/execute` again with the same `requestId` is safe: it does not re-execute the swap, it re-checks the existing one and returns `confirmed` with the signature once it lands. async function executeAndConfirm(body, headers) { for (let i = 0; i < 10; i++) { const res = await fetch('https://api.jup.ag/swap/v2/jupiterz/execute', { method: 'POST', headers: { ...headers, 'Content-Type': 'application/json' }, body: JSON.stringify(body), }).then(r => r.json()); if (res.state !== 'accepted') return res; // confirmed, rejected, invalid or failed await new Promise(r => setTimeout(r, 1000)); } throw new Error('confirmation timed out');} Errors[​](https://jupiterz.jup.ag/docs/integrators/execute#errors "Direct link to Errors") ------------------------------------------------------------------------------------------- | Status | `errorCode` | Cause | | --- | --- | --- | | `400` | `QUOTE_EXPIRED` | The quote's `expireAt` passed before execution | | `400` | — | Malformed `requestId`, `quoteId` or transaction | | `401` | — | Missing or invalid `x-api-key` | | `404` | — | No quote matching this `requestId` | See the [overview](https://jupiterz.jup.ag/docs/integrators/overview#errors) for the full error format. * [Request](https://jupiterz.jup.ag/docs/integrators/execute#request) * [Response](https://jupiterz.jup.ag/docs/integrators/execute#response) * [States](https://jupiterz.jup.ag/docs/integrators/execute#states) * [Pending confirmations](https://jupiterz.jup.ag/docs/integrators/execute#pending-confirmations) * [Errors](https://jupiterz.jup.ag/docs/integrators/execute#errors) --- # Order Endpoints | JupiterZ Documentation [Skip to main content](https://jupiterz.jup.ag/docs/integrators/order#__docusaurus_skipToContent_fallback) On this page `/order` asks every eligible market maker for a price and returns the best one, along with an unsigned transaction ready for the taker to sign. **Method:** `GET` **URL:** `https://api.jup.ag/swap/v2/jupiterz/order` Request[​](https://jupiterz.jup.ag/docs/integrators/order#request "Direct link to Request") -------------------------------------------------------------------------------------------- curl -G 'https://api.jup.ag/swap/v2/jupiterz/order' \ -H 'x-api-key: your-api-key' \ -d inputMint=So11111111111111111111111111111111111111112 \ -d outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v \ -d amount=1000000000 \ -d taker=5v2Vd71VoJ1wZhz1PkhTY48mrJwS6wF4LfvDbYPnJ3bc \ -d swapMode=ExactIn ### Query parameters[​](https://jupiterz.jup.ag/docs/integrators/order#query-parameters "Direct link to Query parameters") | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `inputMint` | string | Yes | Input token mint address | | `outputMint` | string | Yes | Output token mint address | | `amount` | string | Yes | Amount in the token's smallest unit. Input amount for `ExactIn`, output amount for `ExactOut` | | `taker` | string | No | Taker wallet address. **Required to receive a transaction** — see [Indicative quotes](https://jupiterz.jup.ag/docs/integrators/order#indicative-quotes) | | `swapMode` | string | No | `ExactIn` (default) or `ExactOut` | | `version` | string | No | RFQ protocol version. Defaults to `v1` | | `feeBps` | number | No | Market maker fee in basis points (max `10000`) | | `isWsol` | boolean | No | Set when the swap involves wSOL rather than native SOL | | `receiver` | string | No | Address receiving the output tokens, when different from the taker | | `ataAccountPayer` | string | No | Address paying for Associated Token Account creation | | `inputTokenAccount` | string | No | Existing taker-owned input token account. Bypasses ATA derivation | | `outputTokenAccount` | string | No | Existing taker-owned output token account. Bypasses ATA derivation | | `integratorTokenAccount` | string | No | Token account that receives your integrator fee | | `integratorFee` | number | No | Your fee in basis points (max `10000`). Requires `integratorTokenAccount` | | `integratorFeeSide` | string | No | `input` or `output`. Defaults to the user-fixed side: `input` for `ExactIn`, `output` for `ExactOut`. Requires `integratorTokenAccount` | | `settingsPda` | string | No | Squads V5 settings PDA. Required for [vault swaps](https://jupiterz.jup.ag/docs/integration/squads) | | `signers` | string | No | Comma-separated signer pubkeys for Squads vault swaps. The first is the fee payer | note `swapMode` accepts `ExactIn`, `exactIn` and `exact_in` (and the `ExactOut` equivalents). Responses always use the camelCase form: `exactIn` / `exactOut`. Response[​](https://jupiterz.jup.ag/docs/integrators/order#response "Direct link to Response") ----------------------------------------------------------------------------------------------- { "routing": "spot", "requestId": "629bddf3-0038-43a6-8956-f5433d6b1191", "quoteId": "59db3e19-c7b0-4753-a8aa-206701004498", "maker": "maker2p9zXHQ5GKdZjSxLu7BfVz8YmF9oQ7TEd1rWqw", "provider": "MM Trading", "swapMode": "exactIn", "orderInfo": { "input": { "token": "So11111111111111111111111111111111111111112", "startAmount": "1000000000", "endAmount": "1000000000" }, "output": { "token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "startAmount": "200000000", "endAmount": "200000000" } }, "transaction": "AgAAAAAAAAAA...", "expireAt": "1736968572"} | Field | Type | Description | | --- | --- | --- | | `routing` | string | `spot` for RFQ fills | | `requestId` | string | Identifies this quote request. Pass it to `/execute` | | `quoteId` | string | Identifies this specific quote. Pass it to `/execute` | | `maker` | string | Market maker wallet filling the order | | `provider` | string | Human-readable name of the market maker | | `swapMode` | string | `exactIn` or `exactOut` | | `orderInfo.input` | object | Input token and amounts | | `orderInfo.output` | object | Output token and amounts | | `transaction` | string \| null | Base64-encoded versioned transaction to sign. `null` for indicative quotes | | `expireAt` | string \| null | Unix timestamp (seconds) after which the transaction is no longer valid | | `error` | string | Present only when no transaction could be built. See below | `startAmount` and `endAmount` are equal for RFQ fills — market makers quote a firm price, so there is no slippage range. Quote expiry Sign and submit before `expireAt`. Executing an expired quote returns `400` with `errorCode: "QUOTE_EXPIRED"`. ### Indicative quotes[​](https://jupiterz.jup.ag/docs/integrators/order#indicative-quotes "Direct link to Indicative quotes") Two cases return a price but no `transaction`, so you can display pricing before the user is ready to trade: * **No `taker`** — nothing to build a transaction against. `error` is omitted. * **`taker` provided, but the transaction cannot be built** — `error` explains why: | `error` | Meaning | | --- | --- | | `insufficientBalance` | The taker does not hold enough of the input token | | `missingAtaAccount` | A token account required by the swap does not exist on-chain | Always check that `transaction` is non-null before signing. ### No quote available[​](https://jupiterz.jup.ag/docs/integrators/order#no-quote-available "Direct link to No quote available") { "error": "No quote found", "errorCode": "NO_QUOTE_FOUND"} Returned as `404` when no market maker quoted this pair. Fall back to another liquidity source. Global order[​](https://jupiterz.jup.ag/docs/integrators/order#global-order "Direct link to Global order") ----------------------------------------------------------------------------------------------------------- `/global-order` quotes one input mint against **up to 5 candidate output mints** and returns only the leg worth the most in USD. Useful when you don't care which stablecoin (or wrapper) the user ends up with — just which one pays best. **Method:** `GET` **URL:** `https://api.jup.ag/swap/v2/jupiterz/global-order` Parameters are identical to `/order`, with two differences: * `outputMint` takes a **comma-separated list** of 1–5 mints. * `ExactIn` only. curl -G 'https://api.jup.ag/swap/v2/jupiterz/global-order' \ -H 'x-api-key: your-api-key' \ -d inputMint=So11111111111111111111111111111111111111112 \ -d outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v,Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB \ -d amount=1000000000 \ -d taker=5v2Vd71VoJ1wZhz1PkhTY48mrJwS6wF4LfvDbYPnJ3bc The response has the same shape as `/order`. `orderInfo.output.token` tells you which mint won, and `requestId` identifies that winning leg — pass it to `/execute` unchanged. Passing zero mints, or more than 5, returns `400`. * * * **Next:** [Execute Endpoint](https://jupiterz.jup.ag/docs/integrators/execute) — submit the signed transaction * [Request](https://jupiterz.jup.ag/docs/integrators/order#request) * [Query parameters](https://jupiterz.jup.ag/docs/integrators/order#query-parameters) * [Response](https://jupiterz.jup.ag/docs/integrators/order#response) * [Indicative quotes](https://jupiterz.jup.ag/docs/integrators/order#indicative-quotes) * [No quote available](https://jupiterz.jup.ag/docs/integrators/order#no-quote-available) * [Global order](https://jupiterz.jup.ag/docs/integrators/order#global-order) --- # Testing Overview | JupiterZ Documentation [Skip to main content](https://jupiterz.jup.ag/docs/testing/overview#__docusaurus_skipToContent_fallback) On this page This section provides comprehensive testing tools and guidelines for validating your JupiterZ webhook implementation. The tests are written using [Vitest](https://vitest.dev/) . Requirements[​](https://jupiterz.jup.ag/docs/testing/overview#requirements "Direct link to Requirements") ---------------------------------------------------------------------------------------------------------- To run the tests, you need to have the following installed: * [Node.js](https://nodejs.org/en/download/) * [Vitest](https://vitest.dev/) * [pnpm](https://pnpm.io/) Suites[​](https://jupiterz.jup.ag/docs/testing/overview#suites "Direct link to Suites") ---------------------------------------------------------------------------------------- Two suites are available for testing the webhook API, acceptance and integration tests. To install the dependencies for the tests, run: make prepare-tests ### Acceptance tests[​](https://jupiterz.jup.ag/docs/testing/overview#acceptance-tests "Direct link to Acceptance tests") These tests simulate the interaction between the JupiterZ module and the webhook API. The tests are useful to verify that your implementation is compatible with the JupiterZ module, The tests can be found in the `tests/suites/acceptance/` directory in the webhook toolkit repository. To run the tests, you need to provide the webhook URL: WEBHOOK_URL= make run-acceptance-tests you can also provide an api key if your webhook requires it: WEBHOOK_URL= WEBHOOK_API_KEY= make run-acceptance-tests for an example, you can run the tests against the bundled sample server: make run-acceptance-tests-against-sample-server To run the test directly with `pnpm` run: pnpm run acceptance ### Integration tests[​](https://jupiterz.jup.ag/docs/testing/overview#integration-tests "Direct link to Integration tests") Integration tests are end to end tests that simulate the user interaction. The tests are running against our edge (pre-production) environment and require that the webhook has been registered with JupiterZ. The tests can be found in the `tests/suites/integration/` directory in the webhook toolkit repository. TAKER_KEYPAIR= \WEBHOOK_ID= \make run-integration-tests By default, the tests will attempt to get a quote for 1 USDC to SOL, upon a successful quote, the tests will proceed to swap the tokens. To modify the parameters of the quote and swap, you can override the environment variables defined in the `params.ts` file in the webhook toolkit repository. > ⚠️ **Warning**: Running the integration tests will perform a real swap on the Solana mainnet. Make sure you have the necessary funds in your wallet before running the tests. To run the test directly with `pnpm` run: pnpm run integration ### Manual tests[​](https://jupiterz.jup.ag/docs/testing/overview#manual-tests "Direct link to Manual tests") To test a webhook via the [edge UI](https://edge.jup.ag/) with you can use a browser extension ([example](https://chromewebstore.google.com/search/Inssman) ) that allows to modify http request params, adding the rules: * host: `https://preprod.ultra-api.jup.ag/*` * param: `webhookId=` * [Requirements](https://jupiterz.jup.ag/docs/testing/overview#requirements) * [Suites](https://jupiterz.jup.ag/docs/testing/overview#suites) * [Acceptance tests](https://jupiterz.jup.ag/docs/testing/overview#acceptance-tests) * [Integration tests](https://jupiterz.jup.ag/docs/testing/overview#integration-tests) * [Manual tests](https://jupiterz.jup.ag/docs/testing/overview#manual-tests) --- # Frequently Asked Questions | JupiterZ Documentation [Skip to main content](https://jupiterz.jup.ag/docs/faq#__docusaurus_skipToContent_fallback) On this page This section answers common questions about JupiterZ webhook integration, covering technical implementation, business considerations, and operational aspects. General Questions[​](https://jupiterz.jup.ag/docs/faq#general-questions "Direct link to General Questions") ------------------------------------------------------------------------------------------------------------ ### What is JupiterZ?[​](https://jupiterz.jup.ag/docs/faq#what-is-jupiterz "Direct link to What is JupiterZ?") JupiterZ (Request for Quote) is a system that allows market makers to provide liquidity for token swaps through competitive quotes. Instead of using automated market makers (AMMs), users receive quotes directly from registered market makers, often resulting in better prices and lower computational costs. ### Why should I integrate with JupiterZ?[​](https://jupiterz.jup.ag/docs/faq#why-should-i-integrate-with-jupiterz "Direct link to Why should I integrate with JupiterZ?") * **Lower computational costs**: RFQ fills are 10x less CU intensive than AMM swaps * **Better pricing control**: Set your own spreads and manage inventory actively * **Reduced gas volatility**: Not subject to on-chain gas price fluctuations * **Access to Jupiter's user base**: Tap into one of Solana's largest trading platforms ### How do I get started?[​](https://jupiterz.jup.ag/docs/faq#how-do-i-get-started "Direct link to How do I get started?") 1. **Build your webhook**: Implement the three required endpoints (`/tokens`, `/quote`, `/swap`) 2. **Test thoroughly**: Use our acceptance and integration test suites 3. **Contact Jupiter**: Reach out to [dexterdev8 on Telegram](https://t.me/dexterdev8) to register 4. **Go live**: After verification, your webhook will be added to production Technical Implementation[​](https://jupiterz.jup.ag/docs/faq#technical-implementation "Direct link to Technical Implementation") --------------------------------------------------------------------------------------------------------------------------------- ### Does JupiterZ support native SOL?[​](https://jupiterz.jup.ag/docs/faq#does-jupiterz-support-native-sol "Direct link to Does JupiterZ support native SOL?") **Yes**, native SOL is fully supported for both takers (users) and makers. However, market makers should use **WSOL (Wrapped SOL)** in their systems. The order engine program automatically handles SOL wrapping/unwrapping as needed. // Market makers should work with WSOLconst WSOL_MINT = "So11111111111111111111111111111111111111112";// The system automatically handles native SOL for users ### Do I need to account for fees when providing quotes?[​](https://jupiterz.jup.ag/docs/faq#do-i-need-to-account-for-fees-when-providing-quotes "Direct link to Do I need to account for fees when providing quotes?") **No**, you don't need to account for Jupiter's platform fees when generating quotes. The RFQ system applies fees automatically during transaction building. **Example:** * Your quote: 1 SOL → 1000 USDC * With 100 bps (1%) fee: User receives 990 USDC, 10 USDC collected as fee * You only transfer 990 USDC, not 1000 USDC ### Should I verify swap requests?[​](https://jupiterz.jup.ag/docs/faq#should-i-verify-swap-requests "Direct link to Should I verify swap requests?") **Yes**, you should always verify swap requests even though Jupiter's RFQ system also performs verification. This provides an additional layer of security and helps ensure transaction integrity. The Jupiter SDK provides a validation function: import { validateSimilarFillSanitizedMessage } from '@jup-ag/order-engine-sdk';// Use Jupiter's validation functionconst isValid = await validateSimilarFillSanitizedMessage({ transaction: parsedTx, quote: quote, userPublicKey: userPublicKey, makerPublicKey: YOUR_MAKER_PUBLIC_KEY}); ### What happens if I don't provide a quote (return 404)?[​](https://jupiterz.jup.ag/docs/faq#what-happens-if-i-dont-provide-a-quote-return-404 "Direct link to What happens if I don't provide a quote (return 404)?") **No penalty**. It's perfectly acceptable to return `404 Not Found` when you cannot provide a quote. This is expected behavior for scenarios like: * **Unsupported pairs**: You only trade certain token combinations * **Size limitations**: Amount is outside your quoting range * **Market conditions**: Temporarily unable to provide competitive quotes * **Liquidity constraints**: Insufficient inventory for the requested amount **Example scenarios:** // Pair not supportedif (!supportedPairs.includes(`${inputMint}-${outputMint}`)) { return res.status(404).json({ error: "Pair not supported" });}// Amount outside rangeif (amount < MIN_QUOTE_SIZE || amount > MAX_QUOTE_SIZE) { return res.status(404).json({ error: "Amount outside quoting range" });} ### Do faster quotes receive priority?[​](https://jupiterz.jup.ag/docs/faq#do-faster-quotes-receive-priority "Direct link to Do faster quotes receive priority?") **No**, quote speed doesn't affect selection priority. Jupiter dispatches quote requests to all registered webhooks simultaneously and waits for the 250ms timeout. All quotes received within the timeout are compared, and the **best quote value** is selected. However, if two quotes have identical values (unlikely), the faster response will be prioritized as a tiebreaker. ### Are there fees for stable-to-stable swaps?[​](https://jupiterz.jup.ag/docs/faq#are-there-fees-for-stable-to-stable-swaps "Direct link to Are there fees for stable-to-stable swaps?") **No**, stable-to-stable swaps are exempt from Jupiter's platform fees. Examples of stable-to-stable pairs include: * USDC ↔ USDT * USDC ↔ USDH * USDT ↔ USDH ### How long do quotes remain valid?[​](https://jupiterz.jup.ag/docs/faq#how-long-do-quotes-remain-valid "Direct link to How long do quotes remain valid?") Quotes have a **55-second expiry** from creation time: * **20 seconds** reserved for market maker to verify, sign, and submit transaction * **35 seconds** allocated for user to accept the quote * **Frontend auto-refresh**: New quotes are requested every 3 seconds This fixed expiry system simplifies integration by removing the need for custom expiry management. Operational Questions[​](https://jupiterz.jup.ag/docs/faq#operational-questions "Direct link to Operational Questions") ------------------------------------------------------------------------------------------------------------------------ ### What are the performance requirements?[​](https://jupiterz.jup.ag/docs/faq#what-are-the-performance-requirements "Direct link to What are the performance requirements?") #### Response Time Requirements[​](https://jupiterz.jup.ag/docs/faq#response-time-requirements "Direct link to Response Time Requirements") * **Quote requests**: Maximum 250ms response time * **Swap requests**: Maximum 25 seconds response time #### Success Rate Requirements[​](https://jupiterz.jup.ag/docs/faq#success-rate-requirements "Direct link to Success Rate Requirements") * **95% fulfillment rate** for accepted quotes * Falling below 95% in a 1-hour window results in temporary suspension #### Uptime Requirements[​](https://jupiterz.jup.ag/docs/faq#uptime-requirements "Direct link to Uptime Requirements") * High availability expected (99.9%+ uptime recommended) * Consistent 5xx errors will result in temporary suspension ### What happens if my webhook goes offline?[​](https://jupiterz.jup.ag/docs/faq#what-happens-if-my-webhook-goes-offline "Direct link to What happens if my webhook goes offline?") * **Temporary outages**: Jupiter automatically routes traffic to available webhooks * **Extended outages**: Your webhook will be temporarily suspended from receiving requests * **Recovery**: Contact the Jupiter team to re-enable your webhook once issues are resolved ### How is quote selection handled?[​](https://jupiterz.jup.ag/docs/faq#how-is-quote-selection-handled "Direct link to How is quote selection handled?") Jupiter selects quotes based on: 1. **Best value for user**: Highest output amount (ExactIn) or lowest input amount (ExactOut) 2. **Quote simulation**: All quotes must pass transaction simulation 3. **Tiebreaker**: If values are identical, faster response wins ### Can I update my supported tokens dynamically?[​](https://jupiterz.jup.ag/docs/faq#can-i-update-my-supported-tokens-dynamically "Direct link to Can I update my supported tokens dynamically?") **Yes**, Jupiter calls your `/tokens` endpoint every 10 minutes to refresh the supported token list. You can: * Add new tokens by including them in your response * Remove tokens by excluding them from your response * Temporarily disable pairs based on liquidity or market conditions app.get('/tokens', async (req, res) => { // Dynamic token list based on current liquidity const tokensWithLiquidity = await getTokensWithSufficientLiquidity(); res.json(tokensWithLiquidity);}); Technical Support[​](https://jupiterz.jup.ag/docs/faq#technical-support "Direct link to Technical Support") ------------------------------------------------------------------------------------------------------------ ### What information should I provide when seeking help?[​](https://jupiterz.jup.ag/docs/faq#what-information-should-i-provide-when-seeking-help "Direct link to What information should I provide when seeking help?") When contacting support, include: * **Error messages**: Exact error messages and stack traces * **Request id or Quote id** * **Performance data**: Response times and success rates * **Environment details**: Server specifications and network setup ### How does the order engine program work?[​](https://jupiterz.jup.ag/docs/faq#how-does-the-order-engine-program-work "Direct link to How does the order engine program work?") * **Mainnet deployment**: [61DFfeTKM7trxYcPQCM78bJ794ddZprZpAwAnLiwTpYH](https://solscan.io/account/61DFfeTKM7trxYcPQCM78bJ794ddZprZpAwAnLiwTpYH) * **Source code**: Available in the [programs/order-engine](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/programs/order-engine) directory * **IDL**: Interface Definition Language file in [idls directory](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/idls) * **Audit**: [Offside Labs audit report](https://github.com/jup-ag/rfq-webhook-toolkit/blob/main/audits/Jupiter-RFQ-Nov-2024-OffsideLabs.pdf) ### What about the non-standard payload?[​](https://jupiterz.jup.ag/docs/faq#what-about-the-non-standard-payload "Direct link to What about the non-standard payload?") The transaction includes 3 additional bytes of metadata: * **Bytes 1-2**: Fee amount in basis points (u16) * **Byte 3**: Bit mask where LSB indicates swap type (0=ExactIn, 1=ExactOut) This data is for off-chain consumption only and isn't processed by the on-chain program. Still Have Questions?[​](https://jupiterz.jup.ag/docs/faq#still-have-questions "Direct link to Still Have Questions?") ----------------------------------------------------------------------------------------------------------------------- * **Documentation**: Browse other sections of this documentation * **Sample Code**: Check the [server-example](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/server-example) directory * **Direct Support**: Contact [dexterdev8 on Telegram](https://t.me/dexterdev8) for specific integration questions * [General Questions](https://jupiterz.jup.ag/docs/faq#general-questions) * [What is JupiterZ?](https://jupiterz.jup.ag/docs/faq#what-is-jupiterz) * [Why should I integrate with JupiterZ?](https://jupiterz.jup.ag/docs/faq#why-should-i-integrate-with-jupiterz) * [How do I get started?](https://jupiterz.jup.ag/docs/faq#how-do-i-get-started) * [Technical Implementation](https://jupiterz.jup.ag/docs/faq#technical-implementation) * [Does JupiterZ support native SOL?](https://jupiterz.jup.ag/docs/faq#does-jupiterz-support-native-sol) * [Do I need to account for fees when providing quotes?](https://jupiterz.jup.ag/docs/faq#do-i-need-to-account-for-fees-when-providing-quotes) * [Should I verify swap requests?](https://jupiterz.jup.ag/docs/faq#should-i-verify-swap-requests) * [What happens if I don't provide a quote (return 404)?](https://jupiterz.jup.ag/docs/faq#what-happens-if-i-dont-provide-a-quote-return-404) * [Do faster quotes receive priority?](https://jupiterz.jup.ag/docs/faq#do-faster-quotes-receive-priority) * [Are there fees for stable-to-stable swaps?](https://jupiterz.jup.ag/docs/faq#are-there-fees-for-stable-to-stable-swaps) * [How long do quotes remain valid?](https://jupiterz.jup.ag/docs/faq#how-long-do-quotes-remain-valid) * [Operational Questions](https://jupiterz.jup.ag/docs/faq#operational-questions) * [What are the performance requirements?](https://jupiterz.jup.ag/docs/faq#what-are-the-performance-requirements) * [What happens if my webhook goes offline?](https://jupiterz.jup.ag/docs/faq#what-happens-if-my-webhook-goes-offline) * [How is quote selection handled?](https://jupiterz.jup.ag/docs/faq#how-is-quote-selection-handled) * [Can I update my supported tokens dynamically?](https://jupiterz.jup.ag/docs/faq#can-i-update-my-supported-tokens-dynamically) * [Technical Support](https://jupiterz.jup.ag/docs/faq#technical-support) * [What information should I provide when seeking help?](https://jupiterz.jup.ag/docs/faq#what-information-should-i-provide-when-seeking-help) * [How does the order engine program work?](https://jupiterz.jup.ag/docs/faq#how-does-the-order-engine-program-work) * [What about the non-standard payload?](https://jupiterz.jup.ag/docs/faq#what-about-the-non-standard-payload) * [Still Have Questions?](https://jupiterz.jup.ag/docs/faq#still-have-questions) ---