# Account Registration Source: https://docs-test.rye.com/docs/api-v2/account-registration Create a Rye account and get API access in seconds from the developer console. You can create a new Rye account in seconds right from [the developer console](https://staging.console.rye.com/register). You can choose to either sign up using your Google account, or by creating an account with a username/password combination. After you create an account, you can immediately start working with our API. All features of the Rye platform are available immediately. Keep in mind that Rye has [two separate API environments](/docs/api-v2-experimental/environments)β€”staging and productionβ€”and Rye accounts for each environment are completely isolated. This means you will need to create two accounts with Rye; one in each environment. * [**Create a staging account**](https://staging.console.rye.com/register) * [**Create a production account**](https://console.rye.com/register) ## Team accounts We currently do not support team accounts in the Rye console. If you need to share access to a Rye account with team members, then we recommend using a username/password account and sharing the password with your team using a secure password manager. If you originally signed up to Rye using your Google account, then you can add a password by following the reset password flow on the login page. Going through this flow will allow you to continue using OAuth while also letting your team sign in to the same account using a password. # API Comparison: Universal Checkout vs Sync Source: https://docs-test.rye.com/docs/api-v2/api-comparison Compare Rye's Universal Checkout API and Sync API β€” features, supported merchants, architecture, and when to use each. This page compares the Universal Checkout API and the Sync API, outlining their key features, data access, architecture, and pricing models. It highlights when to use each API and how they can be combined for a complete checkout solution. | | **Universal Checkout API** | **Sync API** | | :--------------------- | :------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Summary** | Buy any product on the internet with a valid product URL and buyer identity. | Buy any product from Shopify or Amazon with full product data support. | | **Supported Products** | Any product on the internet. | Any product from Shopify or Amazon. | | **Product Data** | Returns comprehensive product details, including price and availability, from most product URLs on the internet. | Get comprehensive product details, including variant options from Shopify or Amazon only. | | **Architecture** | REST API organized around a checkout intent. | GraphQL API with resources to fetch product data and create and submit a cart. | | **Carts** | No, but multiple quantities of a product are supported. | Yes. | | **Commissions** | Yes commissions. | Yes. | | **Payment Flow** | [Multiple payment flows available](/docs/api-v2/payment-providers). | Charge the user via your payment provider. Rye pays the merchant and deducts the amount from a drawdown deposit you provide. | | **Product Margins** | Supports adding surcharges and order fees, depending on payment flow. | Supports adding surcharges and order fees. | | **Pricing** | \$149/month, first month free. [Details here](https://rye.com/pricing). | GMV-based fee with volume discounts. Deposit required. | | **Webhooks** | Yes, [details here.](/docs/api-v2/webhooks) | Yes, [details here.](https://docs-v1.rye.com/webhooks) | | **Amazon** | Orders are placed through Rye's Amazon account. Any order over \$15 will automatically have Prime shipping applied. | [Orders are placed via your Amazon Business account](https://docs-v1.rye.com/amazon-business/overview#amazon-prime-benefits). To get free Prime shipping, you will need to have Prime enabled on your account. | # Create checkout session Source: https://docs-test.rye.com/docs/api-v2/api-reference/betas/create-checkout-session /openapi.documented.yml post /api/v1/betas/checkout-sessions Create a new checkout session. Checkout sessions are hosted checkout forms your shoppers can use to complete their purchases. # Cancel top-up invoice Source: https://docs-test.rye.com/docs/api-v2/api-reference/billing/cancel-top-up-invoice /openapi.documented.yml delete /api/v1/billing/drawdown/topup/{invoiceId} Cancel/void an unpaid top-up invoice. Only invoices in open state can be cancelled. # Create on-demand top-up invoice Source: https://docs-test.rye.com/docs/api-v2/api-reference/billing/create-on-demand-top-up-invoice /openapi.documented.yml post /api/v1/billing/drawdown/topup Request an on-demand top-up invoice.. Requires drawdown billing to be enabled. Only one unpaid top-up invoice is allowed at a time. # Get billing info Source: https://docs-test.rye.com/docs/api-v2/api-reference/billing/get-billing-info /openapi.documented.yml get /api/v1/billing Get billing configuration and balance for the authenticated developer # Get drawdown balance Source: https://docs-test.rye.com/docs/api-v2/api-reference/billing/get-drawdown-balance /openapi.documented.yml get /api/v1/billing/balance Get current drawdown balance for the authenticated developer # List drawdown transactions Source: https://docs-test.rye.com/docs/api-v2/api-reference/billing/list-drawdown-transactions /openapi.documented.yml get /api/v1/billing/transactions List drawdown balance transactions for the authenticated developer # Setup drawdown billing Source: https://docs-test.rye.com/docs/api-v2/api-reference/billing/setup-drawdown-billing /openapi.documented.yml post /api/v1/billing/drawdown Set up or update drawdown billing for the authenticated developer # Retrieve brand Source: https://docs-test.rye.com/docs/api-v2/api-reference/brands/retrieve-brand /openapi.documented.yml get /api/v1/brands/domain/{domain} Retrieve brand information by domain name Look up a brand by its domain name (e.g. "aloyoga.com" or "www.amazon.com"). Returns brand information including the marketplace type if the lookup succeeds. # Confirm checkout intent Source: https://docs-test.rye.com/docs/api-v2/api-reference/checkout-intents/confirm-checkout-intent /openapi.documented.yml post /api/v1/checkout-intents/{id}/confirm Confirm a checkout intent with provided payment information Confirm means we have buyer's name, address and payment info, so we can move forward to place the order. # Create checkout intent Source: https://docs-test.rye.com/docs/api-v2/api-reference/checkout-intents/create-checkout-intent /openapi.documented.yml post /api/v1/checkout-intents Create a checkout intent with the given request body. # List checkout intents Source: https://docs-test.rye.com/docs/api-v2/api-reference/checkout-intents/list-checkout-intents /openapi.documented.yml get /api/v1/checkout-intents Retrieve a paginated list of checkout intents Enables developers to query checkout intents associated with their account, with filters and cursor-based pagination. # List shipments for checkout intent Source: https://docs-test.rye.com/docs/api-v2/api-reference/checkout-intents/list-shipments-for-checkout-intent /openapi.documented.yml get /api/v1/checkout-intents/{id}/shipments List shipments for a checkout intent # Purchase product Source: https://docs-test.rye.com/docs/api-v2/api-reference/checkout-intents/purchase-product /openapi.documented.yml post /api/v1/checkout-intents/purchase Create a checkout intent and immediately trigger the purchase workflow. This is a "fire-and-forget" endpoint that combines create + confirm in one step. The workflow handles offer retrieval, payment authorization, and order placement asynchronously. Poll the GET endpoint to check status. # Retrieve checkout intent Source: https://docs-test.rye.com/docs/api-v2/api-reference/checkout-intents/retrieve-checkout-intent /openapi.documented.yml get /api/v1/checkout-intents/{id} Retrieve a checkout intent by id Returns checkout intent information if the lookup succeeds. # Retrieve order Source: https://docs-test.rye.com/docs/api-v2/api-reference/checkout-intents/retrieve-order /openapi.documented.yml get /api/v1/checkout-intents/{id}/order Retrieve the order associated with a checkout intent. Returns the single order created when the checkout intent reached the `completed` state. 404 if the intent has not produced an order yet. # List commissions Source: https://docs-test.rye.com/docs/api-v2/api-reference/commissions/list-commissions /openapi.documented.yml get /api/v1/commissions List commissions for the authenticated developer Returns a paginated list of commissions with optional filters using cursor-based pagination. Pass the `endCursor` from a previous response as `after` to fetch the next page, or the `startCursor` as `before` to fetch the previous page. Specifying both `after` and `before` returns 422. # Retrieve commission Source: https://docs-test.rye.com/docs/api-v2/api-reference/commissions/retrieve-commission /openapi.documented.yml get /api/v1/commissions/{id} Retrieve a commission by id Returns commission details for the authenticated developer. # List events Source: https://docs-test.rye.com/docs/api-v2/api-reference/events/list-events /openapi.documented.yml get /api/v1/events Retrieve a paginated list of events. # Retrieve event Source: https://docs-test.rye.com/docs/api-v2/api-reference/events/retrieve-event /openapi.documented.yml get /api/v1/events/{id} Retrieves an event by ID. # Trigger event Source: https://docs-test.rye.com/docs/api-v2/api-reference/events/trigger-event /openapi.documented.yml post /api/v1/events/trigger Trigger a webhook event for a product on demand, in the shape your registered destinations would normally receive. Use during integration testing to exercise your handlers without waiting for an upstream update. The event is targeted at the calling developer only. Pass an `Idempotency-Key` header so retried calls produce the same event ID and the delivery layer dedups. # Create merchant connector installation link Source: https://docs-test.rye.com/docs/api-v2/api-reference/merchant-connectors/create-merchant-connector-installation-link /openapi.documented.yml get /api/v1/merchant-connectors/{connector}/installation-link Generate an installation link for a merchant connector (e.g. Shopify). The returned URL begins the connector's OAuth handshake. Direct the merchant to it; once they authorize the Rye app, the connector redirects back to Rye to complete the install. The merchant is attributed to the calling developer and becomes available for checkout via this account. # Cancel order Source: https://docs-test.rye.com/docs/api-v2/api-reference/orders/cancel-order /openapi.documented.yml post /api/v1/orders/{id}/cancel Request cancellation of an order. Order cancellations are subject to each merchant's cancellation policy. # Get order Source: https://docs-test.rye.com/docs/api-v2/api-reference/orders/get-order /openapi.documented.yml get /api/v1/orders/{id} Retrieve an order by id. # List orders Source: https://docs-test.rye.com/docs/api-v2/api-reference/orders/list-orders /openapi.documented.yml get /api/v1/orders List orders for the authenticated developer with cursor-based pagination. # Update order buyer Source: https://docs-test.rye.com/docs/api-v2/api-reference/orders/update-order-buyer /openapi.documented.yml put /api/v1/orders/{id}/buyer Update buyer fields for an order and update its Shopify shipping address. # Create payment gateway session Source: https://docs-test.rye.com/docs/api-v2/api-reference/payment-gateways/create-payment-gateway-session /openapi.documented.yml post /api/v1/payment-gateways/{gateway}/session Create a payment gateway session for client-side card tokenization. Returns short-lived credentials scoped to the authenticated developer. Use the credentials with the corresponding gateway's client-side SDK to tokenize a card. Tokens created this way are locked to the developer's container and cannot be used by other developers. # List product subscriptions Source: https://docs-test.rye.com/docs/api-v2/api-reference/products/list-product-subscriptions /openapi.documented.yml get /api/v1/products/subscriptions Retrieve product subscription rules. # Lookup product Source: https://docs-test.rye.com/docs/api-v2/api-reference/products/lookup-product /openapi.documented.yml get /api/v1/products/lookup Lookup a product's information by URL. # Subscribe to product events Source: https://docs-test.rye.com/docs/api-v2/api-reference/products/subscribe-to-product-events /openapi.documented.yml post /api/v1/products/subscribe Subscribe to product events from a store. # Unsubscribe from product events Source: https://docs-test.rye.com/docs/api-v2/api-reference/products/unsubscribe-from-product-events /openapi.documented.yml post /api/v1/products/unsubscribe Unsubscribe from product events from a store. # Create return Source: https://docs-test.rye.com/docs/api-v2/api-reference/returns/create-return /openapi.documented.yml post /api/v1/returns Create a return for a completed order. Whole-order returns only β€” the order's line items are enumerated for you. The return is submitted for approval and then progresses asynchronously toward the refund; poll the returned return id (or listen for webhooks) to follow its state. # Get return Source: https://docs-test.rye.com/docs/api-v2/api-reference/returns/get-return /openapi.documented.yml get /api/v1/returns/{returnId} Fetch a Return by id. Tenancy is scoped to the authenticated developer. # List shipments Source: https://docs-test.rye.com/docs/api-v2/api-reference/shipments/list-shipments /openapi.documented.yml get /api/v1/shipments Retrieve a paginated list of shipments Enables developers to query shipments associated with their account, with filters and cursor-based pagination. # Retrieve shipment by id Source: https://docs-test.rye.com/docs/api-v2/api-reference/shipments/retrieve-shipment-by-id /openapi.documented.yml get /api/v1/shipments/{id} Retrieve a shipment by id Returns shipment information if the lookup succeeds. # Advance simulated shipment Source: https://docs-test.rye.com/docs/api-v2/api-reference/test-helpers/advance-simulated-shipment /openapi.documented.yml post /api/v1/test-helpers/checkout-intents/{checkoutIntentId}/shipments/advance Advance the simulated shipment for a checkout intent. To trigger delayed or canceled shipping scenarios, create the checkout intent with a matching shipping and delivery test product: https://rye.com/docs/api-v2/testing/test-products#shipping-&-delivery # Approve simulated return Source: https://docs-test.rye.com/docs/api-v2/api-reference/test-helpers/approve-simulated-return /openapi.documented.yml post /api/v1/test-helpers/returns/{returnId}/approve Approve a simulated return. # Create simulated return Source: https://docs-test.rye.com/docs/api-v2/api-reference/test-helpers/create-simulated-return /openapi.documented.yml post /api/v1/test-helpers/returns Create a simulated return for an order, then drive it through its lifecycle with the approve/deny/refund/fail helpers below. # Deny simulated return Source: https://docs-test.rye.com/docs/api-v2/api-reference/test-helpers/deny-simulated-return /openapi.documented.yml post /api/v1/test-helpers/returns/{returnId}/deny Deny a simulated return. # Fail simulated return Source: https://docs-test.rye.com/docs/api-v2/api-reference/test-helpers/fail-simulated-return /openapi.documented.yml post /api/v1/test-helpers/returns/{returnId}/fail Mark a simulated return as failed. # Refund simulated return Source: https://docs-test.rye.com/docs/api-v2/api-reference/test-helpers/refund-simulated-return /openapi.documented.yml post /api/v1/test-helpers/returns/{returnId}/refund Refund a simulated return using the order total as the simulated refund amount. # Authorization Source: https://docs-test.rye.com/docs/api-v2/authorization Authenticate requests to the Rye API using your API key in the Authorization header. All requests to the Rye API must include an `Authorization` header containing your API key. This key authenticates your requests and allows you to access all available endpoints. **Important:** Keep your API key private. Anyone with access to it can make requests on your behalf. If you suspect your key has been compromised, [contact us immediately](support@rye.com) to generate a new one. ## Using Your API Key Include your API key in the `Authorization` header of every request: ``` Authorization: Basic YOUR_API_KEY ``` ## Environment-Specific Keys Each API environment has a unique key: * **Staging API key:** Works only in the staging environment. * **Production API key:** Works only in the production environment. Make sure you are using the correct key for the environment you are targeting. Staging keys will not work in production and vice versa. ## Retrieving Your API Key 1. Log in to the Rye console. 2. Navigate to the [Account page](https://staging.console.rye.com/account) -> API Key Headers section. 3. View and copy your API key. ## Best Practices * Never embed your API key in client-side code or publicly-accessible repositories. * Use environment variables or a secure key management system to store and access your API keys in your applications. # Submit Orders to Best Buy Source: https://docs-test.rye.com/docs/api-v2/best-buy How to get approved and submit orders to Best Buy through Rye's Universal Checkout API. Our Best Buy integration uses the same ordering workflow and API endpoints as submitting orders to other merchants. Before submitting live orders, your production Rye account must be allowlisted. Once approved, you can submit orders in production using Best Buy product URLs. A few important details to be aware of are listed below, including the approval process, product limitations, and branding guidelines. ## Example You can test the Best Buy ordering workflow using [our staging environment](https://docs.rye.com/api-v2/environments) without being allowlisted. Below is an example using our [single-step checkout workflow](https://docs.rye.com/api-v2/example-flows/single-step-checkout). You can also submit Best Buy orders through our [multi-step checkout workflow](https://docs.rye.com/api-v2/example-flows/simple-checkout) if you need to retrieve pricing and availability details before placing the order. ```bash curl theme={null} curl https://staging.api.rye.com/api/v1/checkout-intents/purchase \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $CHECKOUT_INTENTS_API_KEY" \ -d '{ "buyer": { "address1": "123 Main St", "city": "New York", "country": "US", "email": "john.doe@example.com", "firstName": "John", "lastName": "Doe", "phone": "212-333-2121", "postalCode": "10001", "province": "NY" }, "paymentMethod": { "stripeToken": "tok_visa", "type": "stripe_token" }, "productUrl": "https://www.bestbuy.com/product/apple-airtag-silver/JJGCQ8XFQY", "quantity": 1 }' ``` ```javascript TypeScript SDK theme={null} import CheckoutIntents from 'checkout-intents'; const client = new CheckoutIntents({ apiKey: process.env['CHECKOUT_INTENTS_API_KEY'], }); const checkoutIntent = await client.checkoutIntents.purchase({ buyer: { address1: '123 Main St', city: 'New York', country: 'US', email: 'john.doe@example.com', firstName: 'John', lastName: 'Doe', phone: '212-333-2121', postalCode: '10001', province: 'NY', }, paymentMethod: { stripeToken: 'tok_visa', type: 'stripe_token' }, productUrl: 'https://www.bestbuy.com/product/apple-airtag-silver/JJGCQ8XFQY', quantity: 1, }); console.log(checkoutIntent); ``` ```python Python SDK theme={null} import os from checkout_intents import CheckoutIntents api_key = os.environ["RYE_API_KEY"] client = CheckoutIntents(api_key) checkout_intent = client.checkout_intents.create( buyer={ "address1": "123 Main St", "city": "New York", "country": "US", "email": "john.doe@example.com", "first_name": "John", "last_name": "Doe", "phone": "212-333-2121", "postal_code": "10001", "province": "NY", }, product_url="https://www.bestbuy.com/product/apple-airtag-silver/JJGCQ8XFQY", quantity=1, ) ``` ```ruby Ruby SDK theme={null} require "checkout_intents" checkout_intents = CheckoutIntents::Client.new( api_key: ENV["CHECKOUT_INTENTS_API_KEY"], environment: "staging" ) checkout_intent = checkout_intents.checkout_intents.purchase( buyer: { address1: "123 Main St", city: "New York", country: "US", email: "john.doe@example.com", firstName: "John", lastName: "Doe", phone: "212-333-2121", postalCode: "10001", province: "NY" }, payment_method: {stripeToken: "tok_visa", type: "stripe_token"}, product_url: "https://www.bestbuy.com/product/apple-airtag-silver/JJGCQ8XFQY", quantity: 1 ) ``` ## Approval Process Use of our Best Buy integration is subject to approval from Best Buy. If submit a Best Buy order in production without prior approval, you will receive an error response from the API. [Please email us](mailto:support@rye.com) to request approval for Best Buy ordering. Include a short description of your app, the Best Buy product categories you are interested in, and screenshots of the experience where you plan to display Best Buy products. Once you submit this information, we will coordinate with Best Buy on the approval process. ## Key Details * **Branding Guidelines:** * When displaying Best Buy products in your app, [the Best Buy logo](https://corporate.bestbuy.com/bby-logo-white-background/) must be shown alongside any items from Best Buy. Ensure there is a space equal to 1x the height of the yellow tag separating the logo from any surrounding content. * On your PDP, you must also note to shoppers that products are fulfilled by Best Buy. * **Commissions:** Based on your agreement with Best Buy and Rye, any commissions are paid 30 days after the purchase is completed. This allows time for order confirmation, fulfillment, and potential returns. * **Payments:** All [payment providers](/docs/api-v2/payment-providers) are supported, including drawdown. Best Buy orders are placed using a dedicated billing account per developer. * **Product Availabilty:** Only first-party inventory is supported through this integration. Some products on the Best Buy website are sold by third-party sellers. For those items, we are unable to fetch offers or submit orders. * **Delivery:** Only home shipping is supported (P.O. boxes and in-store pickup are not available). Orders over \$35 generally qualify for free shipping, but the [exact shipping cost can be confirmed through the API](https://docs.rye.com/api-v2/example-flows/simple-checkout#step-5:-confirm-final-pricing). # Changelog Source: https://docs-test.rye.com/docs/api-v2/changelog **πŸ› Bug Fixes** * Tracking events for Amazon orders now update continuously * Clearer error when an Amazon product is not found (`product_not_found`) * Card authorization now released when a checkout intent expires, so shoppers get refunded sooner * Fixed intermittent webhook delivery failures **✨ Features** * A new endpoint supports programmatic drawdown top-ups, useful if you don't use traditional banking rails to store funds. # Checkout Intent Lifecycle Source: https://docs-test.rye.com/docs/api-v2/checkout-intent-lifecycle Understand the states a Checkout Intent progresses through, from creation and offer retrieval to order placement and completion. A Checkout Intent represents the end‑to‑end process of purchasing a product through Rye. Each intent progresses through a series of states, from initial creation to final order placement. Understanding these states helps you design robust checkout flows and handle errors gracefully. ## States * `retrieving_offer` - When a Checkout Intent is first created, Rye fetches live pricing, availability, taxes, and shipping options from the merchant for the provided `productUrl`. * `awaiting_confirmation` - An offer is ready and includes pricing and availability details. Your app can collect payment details from the buyer. * `placing_order` - A payment method was provided and Rye is executing the checkout on the merchant site. * `completed` - The order was successfully placed and confirmed by the merchant. * `failed` - The checkout could not be completed (e.g., out of stock, unsupported merchant, declined payment). ```mermaid theme={null} stateDiagram-v2 [*] --> retrieving_offer: Create Checkout Intent retrieving_offer --> awaiting_confirmation retrieving_offer --> failed awaiting_confirmation --> placing_order: Confirm Checkout Intent awaiting_confirmation --> failed placing_order --> completed placing_order --> failed completed --> [*] failed --> [*] ``` ## Sequence The diagram below shows the typical happy path (Create -> Confirm -> Fulfill) plus common branches. ```mermaid theme={null} sequenceDiagram autonumber actor User participant Your App participant Rye API Note over Your App,Rye API: 1. Create an intent with buyer and product URL Your App->>Rye API: POST /api/v1/checkout-intents { buyer, productUrl, quantity } Rye API-->>Your App: 201 Created { id, state: "retrieving_offer" } Note over Rye API: Fetch live offer (price, tax, shipping) Rye API-->>Your App: 200 OK { id, state: "awaiting_confirmation", offer: {...} } Note over User,Your App: 2. Collect payment method User->>Your App: Enters card details Your App->>Rye API: POST /api/v1/checkout-intents/{id}/confirm { paymentMethod: {...} } Rye API-->>Your App: 200 OK { id, state: "placing_order" } Note over Rye API: Execute merchant checkout with confirmed funds Rye API-->>Your App: 200 OK { id, state: "completed", order: {...} } alt Failure cases Rye API-->>Your App: 4xx/5xx { id, state: "failed", error: {...} } end ``` ## Notes * **Polling Duration:** Developers should poll for up to 45 minutes during the `retrieving_offer state`, as the checkout intent may take that long to transition to the `awaiting_confirmation` state. * **Checkout Intent Window:** Developers have 45 minutes to confirm a checkout intent. The timer starts as soon as the checkout intent is created in our system. After that time, the checkout intent will be expired and in a `failed` state, and any confirmation requests for the checkout intent will return a `checkout_intent_expired` as the failure reason. # API Limitations Source: https://docs-test.rye.com/docs/api-v2/developer-notes This page outlines the current limitations to keep in mind when integrating with the API. ## Ordering & Checkout **All Orders** * Login or non-guest checkout flows are not supported. * Only physical products are supported at this time. * US-only ordering is supported. * Additional regions can be supported on request for enterprise use cases. * One product per checkout is required. Multiple quantities of the same product are supported, but multi-product carts are not supported yet. * Stores with advanced anti‑bot mechanisms (such as REI or Sephora) are not yet supported. * Product variants (such as size or color) are supported via the `variantSelections` field or by providing a variant-specific product URL. See the [Variants](/docs/api-v2/variants) guide for details. * Shipping options default to the first option returned (usually the lowest cost). You cannot yet select from multiple options. * Checkout intents cannot be updated once created. To change buyer details such as the shipping address, you need to create a new checkout intent with the updated information. **Merchant of Record & Payment Flows** * Rye supports multiple [payment providers](/docs/api-v2/payment-providers). With Stripe, Rye is the merchant of record. With Basis Theory, the card is forwarded directly to the merchant’s payment vault (e.g., Shopify), so Rye is not the merchant of record for Shopify orders. **Variant Selection** * Use the [product lookup endpoint](/docs/api-v2/api-reference/get-product) to retrieve available variant dimensions and values before placing an order. * The `variantSelections` field lets you specify which variant to purchase. Labels are fuzzy-matched (e.g., "Colour" matches "Color"), but values must match exactly (case-insensitive). If no variant matches, the API returns a `variant_selections_invalid` error. * Alternatively, if the `productUrl` already includes the variant identifier, you don’t need to include `variantSelections`. When both are provided, `variantSelections` takes precedence. * When using `variantSelections`, pass the exact option labels and values from the product data, not a variant ID. For example:\ `[{ label: β€˜Size’, value: β€˜8.5’ }, { label: β€˜Color’, value: β€˜Blue’ }]`. ## Post-Purchase * Orders placed agentically are not tracked post-purchase. Rye’s API places orders on the store website acting on behalf of the end-user. If the end-user has provided an email and/or phone number, they will directly receive tracking information. * Orders placed on supported marketplaces (Best Buy, Shopify) *are* tracked post-purchase. Updates can be retrieved either via API or by webhook. * Returns: Buyers would need to contact the merchant directly for returns. They can use the details from the order confirmation email to help the merchant find the order. # Environments Source: https://docs-test.rye.com/docs/api-v2/environments Staging and production environments for the Rye API. Start in staging to test without real orders, then go live in production. ## Overview All API calls occur in either our staging or production environment. Our staging environment acts as a sandbox. Developers can safely work on their integration without the risk of placing real orders or charging real credit cards. The staging environment is where all new API integrations begin. After working on your integration in the staging environment, you can go live and launch to customers using our production environment. In production, it is possible to charge real payment methods and purchase products from the various marketplaces the REST API supports. Both environments are **completely isolated** from each other to ensure security. A cart belonging to a customer in your production environment is inaccessible in the staging environment, and vice versa. Each environment uses a separate API key for authentication. ## Switching Enviroments in Console Once you are signed in the Console to either environment, you will see a switch in the top-right corner of the page which tells you which environment you are currently signed in to. Clicking this switch will swap your browser between each environment. Below you can see an example of what this looks like when signed in to the staging environment: Keep in mind that because each environment is isolated from the other, your authentication headers will be different for each environment. Using your staging API key to make requests to our production API will result in an authorization error, and vice versa. ## API Endpoints by Environment Below you can find the REST API endpoints for each environment. When making requests you will need to provide [authorization headers](/docs/api-v2-experimental/authorization) for your account in that environment for your requests to run successfully. | Environment | Console | Base API URL | | -------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------- | | **Staging** | [https://staging.console.rye.com](https://staging.console.rye.com) | [https://staging.api.rye.com/api/v1/](https://staging.api.rye.com/api/v1/) | | **Production** | [https://console.rye.com](https://console.rye.com) | [https://api.rye.com/api/v1/](https://api.rye.com/api/v1/) | ## Differences Between Staging and Production Environments * Order Placement * No actual orders will be placed through the /confirm endpoint in staging. You can use this to test order flows safely without affecting live inventory or fulfillment. * Payments * Payments in the staging environment use Stripe test cards. No real financial transactions are processed. * You can find a full list of supported Stripe test cards in the official Stripe documentation: [Stripe Test Cards](https://docs.stripe.com/testing) * Use the following Stripe API key to tokenize credit card information: `pk_test_51LgDhrHGDlstla3fdqlULAne0rAf4Ho6aBV2cobkYQ4m863Sy0W8DNu2HOnUeYTQzQnE4DZGyzvCB8Yzl1r38isl00H9sVKEMu` ## Rate Limits See the [Rate Limits](/docs/api-v2/rate-limits) guide for the current limits, response headers, and recommended client handling. # Handling API Errors Source: https://docs-test.rye.com/docs/api-v2/errors HTTP status codes, error messages, and resolution steps for common Rye API errors. Our API uses standard HTTP status codes to indicate the success or failure of a request. When an error occurs, the response will include an error code and message. Your integration should handle these gracefully, with retry logic where appropriate, and surface clear messages to users when action is required. | Status Code | Message | How to Resolve | | ----------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------- | | **400** | Bad Request | Check your request payload and parameters for missing or invalid fields. | | **401** | Unauthorized | Ensure you are using the correct API key. | | **403** | Forbidden | Your API key does not have permission. Confirm access rights or contact support. | | **404** | Not Found | Verify the endpoint URL and resource ID. | | **409** | Conflict | The resource is in an invalid state (e.g., duplicate request). Retry if safe. | | **422** | Unprocessable Entity | Input validation failed. Check field formats and required attributes. | | **429** | Too Many Requests | You have exceeded the rate limit. See [Rate Limits](/docs/api-v2/rate-limits) for limits, headers, and retry guidance. | | **500** | Internal Server Error | Temporary server issue. Retry the request or contact support if persistent. | | **503** | Service Unavailable | API is temporarily unavailable. Retry with backoff. | **Specific Error Cases** * A 404 error can occur if an order confirmation request is submitted before the order reaches `awaiting_confirmation`. Adding a short delay or polling until the order is ready will help prevent this error. * When creating a checkout intent, the `buyer.country` field is case sensitive. The expected input is uppercase. * If you get an `Order Failed: No such token` error, confirm that you are generating the card token with [the Rye publishable key](https://docs.rye.com/api-v2/payment-providers/stripe#generate-a-stripe-token-using-react-app), rather than your own Stripe key. * `constraint_total_price_exceeded` and `constraint_shipping_cost_exceeded` are returned when the order total or shipping cost exceeds the value specified in the checkout request. * If you get the error `The specified phone number does not match the expected pattern`, please update the phone number in your request to use the format `010-010-0101`. # Build an AI chat storefront with Rye and Stripe in Next.js Source: https://docs-test.rye.com/docs/api-v2/example-flows/chat-storefront Build a conversational AI storefront where users discover and purchase products through chat, using Rye's checkout API and Stripe. Learn how to build an agentic checkout flow: discover product URLs in chat, capture buyer identity, tokenize card details with Stripe, and confirm a Rye Checkout Intent to place the order. ## Who this is for Developers building AI chat interfaces where users can buy physical products across Amazon, Shopify, and beyond. We’ll use the [Vercel AI SDK](https://ai-sdk.dev/docs/introduction) for tool-calling, [Stripe Elements](https://docs.stripe.com/payments/elements) for card collection, and Universal Checkout API for submitting orders via Checkout Intents. ## What you'll build A minimal Next.js app with a streaming chat. The assistant can: 1. Search Amazon (and the wider web) to surface real product URLs. 2. Show a Buy button next to results. 3. Open a modal that collects buyer identity (name, email, phone) and creates a Checkout Intent with Rye. 4. Collect card details using Stripe Card Element and tokenize on the client. 5. Confirm the Checkout Intent by sending the Stripe token to Rye, which places the order on the third‑party site. We'll do this with clean file boundaries so you can drop this into an existing project. ## See Rye in Action Watch a complete order flow β€” from product URL to purchase confirmation β€” all without leaving your app. AI chat storefront with Rye ```mermaid theme={null} sequenceDiagram autonumber actor User as End User (Browser) participant Stripe as Stripe participant Next as Next.js participant Rye as Rye API participant Merchant as Merchant (Amazon/Shopify) User->>Next: "Find stainless steel bottle under $30" Next-->>User: Streaming chat + product gallery User->>Next: Click "Buy" (opens modal) User->>Next: Submit Buyer Info + Product URL Next->>Rye: POST /checkout-intents {buyer, productUrl} Rye->>Merchant: Fetch price/availability/shipping Merchant-->>Rye: Offer (subtotal, tax, shipping) Rye-->>Next: Checkout Intent(state=retrieving_offer) Next-->>User: Show Order Summary when awaiting_confirmation User->>Stripe: Enter card in Card Element Stripe-->>User: payment method (token) User->>Next: POST /confirm-intent (checkoutIntentId, token) Next->>Rye: POST /checkout-intents/:id/confirm (token) Rye->>Merchant: Place order Merchant-->>Rye: Order result Rye-->>Next: CheckoutIntent(state=completed|failed) Next-->>User: "Order placed!" ``` You can follow along step-by-step, or [clone the demo repo](https://github.com/cjavdev/rye-ai-chatbot) to run the example. ## Assumptions * Next.js App Router on Node 18+. * You have a Rye API key and will start in staging. * You have Rye's Stripe publishable key * Staging: `pk_test_51LgDhrHGDlstla3fdqlULAne0rAf4Ho6aBV2cobkYQ4m863Sy0W8DNu2HOnUeYTQzQnE4DZGyzvCB8Yzl1r38isl00H9sVKEMu` * We'll use the [AI SDK's tool-calling](https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling) with OpenAI, but you can use a different LLM provider if you'd like. ## Project structure This is the general structure of the application and how we'll organize our files. ``` app/ layout.tsx page.tsx api/ chat/route.ts checkout/create-intent/route.ts checkout/confirm-intent/route.ts checkout/get-intent/route.ts components/ Chat.tsx ChatInput.tsx CheckoutModal.tsx messages/ Message.tsx ProductGalleryMessage.tsx lib/ rye.ts types.ts tools/ amazon.ts ``` If you prefer server actions instead of route handlers, you can mirror the same logic in `app/actions.tsx`. ## Setup Create the starter template: ```bash theme={null} npx create-next-app@latest ``` These are the options we'll use for the demo: ```bash theme={null} Need to install the following packages: create-next-app@15.5.0 Ok to proceed? (y) y βœ” What is your project named? … my-app βœ” Would you like to use TypeScript? … Yes βœ” Which linter would you like to use? β€Ί None βœ” Would you like to use Tailwind CSS? … Yes βœ” Would you like your code inside a `src/` directory? … Yes βœ” Would you like to use App Router? (recommended) … Yes βœ” Would you like to use Turbopack? (recommended) … No βœ” Would you like to customize the import alias (`@/*` by default)? … Yes Creating a new Next.js app in /Users/cjav_dev/repos/rye/demo-test/my-app. ``` ### Add dependencies First, install libraries for working with LLMs: ```bash theme={null} npm install ai @ai-sdk/openai @ai-sdk/react zod ``` Next, we'll install some libraries for collecting payment methods: ```bash theme={null} npm install @stripe/stripe-js @stripe/react-stripe-js ``` We'll use these tools for working rendering markdown and parsing HTML. ```bash theme={null} npm install cheerio react-markdown ``` ### Set environment variables Create a `.env` file with these environment variables set. | | | | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `OPENAI_API_KEY` | [https://platform.openai.com/settings/organization/api-keys](https://platform.openai.com/settings/organization/api-keys) | | `RYE_API_KEY` | [https://staging.console.rye.com/account](https://staging.console.rye.com/account) | | `RYE_API_BASE` | Either [https://staging.console.rye.com/account](https://staging.console.rye.com/account) or [https://console.rye.com/account](https://console.rye.com/account) | | `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` | Use Rye's Stripe Publishable Key. | ```bash theme={null} // .env OPENAI_API_KEY=sk-... RYE_API_KEY=U... # https://staging.console.rye.com/account or https://console.rye.com/account RYE_API_BASE=https://staging.api.rye.com NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_51LgDhrHGDlstla3fdqlULAne0rAf4Ho6aBV2cobkYQ4m863Sy0W8DNu2HOnUeYTQzQnE4DZGyzvCB8Yzl1r38isl00H9sVKEMu ``` At this point, you should be able to run `npm run dev` and load the starter app in the browser. ## 1. Create a basic AI Chat app We'll build this chat-based storefront incrementally, starting with a basic AI chat interface that we'll progressively enhance with commerce capabilities. This approach allows us to establish the core conversational flow first, then layer on product search tools, checkout flows, and payment processing. By the end, you'll have a complete chat experience where users can discover products through natural conversation, review detailed offers with real-time shipping and tax calculations, and complete purchases seamlesslyβ€”all powered by Rye's commerce infrastructure. ### Set up minimal layout Before we dive into chat components, let's set up a minimal layout. ```ts app/layout.tsx theme={null} import "./globals.css"; import Link from 'next/link' export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return (
Rye Demo
{children}
); } ``` ```ts app/page.tsx theme={null} import Chat from "./components/Chat"; export default function Home() { return (
); } ```
### Set up the chat API endpoint To connect our chat interface to an AI model, we need to set up a server-side API route that handles streaming responses from OpenAI's GPT-5. This endpoint will process incoming messages, send them to the language model, and stream back responses that our client-side chat components can display in real-time. While we're starting with basic chat functionality, this foundation is designed to easily accommodate tools for product search and other enhanced features later. ```ts app/api/chat/route.ts theme={null} import { openai } from '@ai-sdk/openai'; import { convertToModelMessages, InferUITools, stepCountIs, streamText, UIDataTypes, UIMessage, } from 'ai'; // TODO: Add tools to handle product discovery. const tools = {}; export type UseChatToolsMessage = UIMessage< never, UIDataTypes, InferUITools >; export async function POST(req: Request) { const { messages } = await req.json(); const result = streamText({ model: openai('gpt-5'), system: `You are a helpful AI assistant that can search for products on Amazon and assist with various tasks.`, messages: await convertToModelMessages(messages), stopWhen: stepCountIs(3), // multi-steps for server-side tools tools, }); return result.toUIMessageStreamResponse({ originalMessages: messages }); } ``` ### Build the chat interface The chat components handle user input, display responses, and provide the foundation for our upcoming product search and checkout features. For now, they manage basic messagingβ€”we'll add search results, Buy buttons, and checkout modals next. The Chat component will eventually manage our Checkout Modal and rendering fulfillment messages, but to start it'll contain a stream of messages. The `useChat` hook allows us to connect to the Next.js server endpoint that calls the LLM provider. ```ts app/components/Chat.tsx theme={null} 'use client'; import ChatInput from './ChatInput'; import Message from './messages/Message'; import { useChat } from '@ai-sdk/react'; import { DefaultChatTransport, lastAssistantMessageIsCompleteWithToolCalls, } from 'ai'; import { UseChatToolsMessage } from '@/app/api/chat/route'; import { useEffect, useRef, useState } from 'react'; export default function Chat() { const messagesEndRef = useRef(null); const { messages, sendMessage, addToolResult, status } = useChat({ transport: new DefaultChatTransport({ api: '/api/chat' }), sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls, }); useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages]); return (
{messages?.map(message => ( ))} {/* Scroll anchor */}
sendMessage({ text })} />
); } ``` The `ChatInput` component provides a text area for users to type and submit messages. ```ts app/components/ChatInput.tsx theme={null} import { useState } from 'react'; export default function ChatInput({ status, onSubmit, }: { status: string; onSubmit: (text: string) => void; }) { const [text, setText] = useState(''); return (
{ e.preventDefault(); if (text.trim() === '') return; onSubmit(text); setText(''); }} >