When to use gasless: You’re building a consumer-facing product where users shouldn’t think about gas. For solvers and aggregators executing trades programmatically, see the self-execution quickstart.
How It Differs from Self-Execution
| Self-execution | Gasless (API default) | |
|---|---|---|
| Quote request | gasless=false | gasless=true (default) + approval params |
| Who submits tx | You broadcast via your RPC | Bebop submits on-chain |
| Order endpoint | Not used - tx comes from /v3/quote | POST signature to /v3/order |
| Last look | No - quote is firm once signed | Yes - maker can reject |
| Gas cost | Paid by taker | Paid by Bebop |
| Token approvals | Standard approve on settlement contract | Standard or Permit2 |
1. Request a Gasless Quote
Addgasless=true and the relevant approval parameters to your quote request:
Approval Parameters
| Parameter | Description |
|---|---|
gasless | Set to true to enable gasless mode |
approval_type | Standard (default) or Permit2 - controls how token approvals are handled |
2. Sign the Quote
Sign the EIP-712 typed data from the quote response - the same signing flow as self-execution:RFQ_EIP712_TYPES dictionary contains the EIP712Domain and all three order type definitions. The API selects the order type automatically based on the trade structure - use the onchainOrderType from the quote response as your primaryType.
EIP-712 order type schemas
EIP-712 order type schemas
| Type | When used | Key differences |
|---|---|---|
SingleOrder | One-to-one trades | Scalar fields: maker_address, taker_token, taker_amount |
MultiOrder | Single maker, multiple tokens | Array fields: taker_tokens[], taker_amounts[] |
AggregateOrder | Multiple makers | Nested arrays: taker_tokens[][], maker_addresses[] |
3. Submit the Order
Unlike self-execution, gasless orders are submitted to Bebop’s/v3/order endpoint. Bebop handles the on-chain settlement:
4. Monitor Settlement
Poll the order status endpoint to track progress:Order Statuses
| Status | Meaning |
|---|---|
Pending | Bebop received the order and is preparing to submit |
Success | Maker accepted - transaction is being broadcast |
Settled | Transaction confirmed on-chain - tokens have been transferred |
Confirmed | Final success state - settlement fully confirmed |
Failed | Order failed. Covers last look rejections, on-chain failures, expiry, and validation errors. |
order-status response also includes txHash (when available) and amounts (received token amounts after settlement).
Full Example
Dependencies:
pip install httpx eth_account (or uv add httpx eth_account)Using Permit2 Approvals
Withapproval_type=Standard, the user must have approved the settlement contract before trading (a one-time on-chain transaction per token). Permit2 removes this requirement by using an off-chain signature for token approvals instead.
This differs from the Aggregation API’s Permit2 flow. The Aggregation API wraps the order inside
PermitBatchWitnessTransferFrom - you sign a single combined message. The RFQ API keeps order signing unchanged and adds a separate PermitBatch signature for token approvals.How it works
-
One-time setup: Approve the Permit2 contract (
0x000000000022D473030F116dDEE9F6B43aC78BA3) for your sell tokens. This is a standard ERC-20approve()- the same kind of transaction you’d do for the settlement contract with Standard approvals, but targeting the Permit2 contract instead. -
Request a quote with
approval_type=Permit2:
-
Sign the order the same way as Standard -
BebopSettlementdomain, same order types. ThetoSigndata is identical. -
Check
requiredSignaturesin the quote response. If it contains token addresses, generate aPermitBatchsignature:
- POST to
/orderwith the additionalpermit2field:
On subsequent trades for the same token,
requiredSignatures will be empty once the Permit2 allowance is active. In that case, no permit2 field is needed in the POST body - it works the same as Standard.permit2 Field Reference
| Field | Type | Description |
|---|---|---|
signature | string | Hex-encoded PermitBatch EIP-712 signature |
approvals_deadline | integer | Unix timestamp - must match sigDeadline in the signed PermitBatch |
token_addresses | string[] | Token addresses from requiredSignatures |
token_nonces | integer[] | Permit2 nonces for each token (from allowance() call) |