Oberlo was discontinued in June 2022 by Shopify and no longer exists. There is no Oberlo API to integrate with Bolt.new. Build the same dropshipping functionality using Oberlo's official successors: DSers (the recommended AliExpress dropshipping tool), Spocket (US/EU suppliers), or Printful (print-on-demand). This guide shows how to build a product import and order management tool in Bolt using these active dropshipping platforms.
Build Dropshipping Features in Bolt.new Using Oberlo's Active Successors
Oberlo launched in 2015 as a Shopify app that made it easy to import products from AliExpress into Shopify stores and automate order fulfillment. It became one of the most popular dropshipping tools for independent e-commerce entrepreneurs, processing millions of orders before Shopify acquired it in 2017. In June 2022, Shopify announced Oberlo's discontinuation, citing a strategic focus on their own fulfillment capabilities and a partnership with DSers as the official migration path. The Oberlo app stopped functioning on June 15, 2022. Any Oberlo API documentation, GitHub repositories, or tutorials predating that date describe a product that no longer exists.
The dropshipping ecosystem has continued without Oberlo, and the alternatives are more capable. DSers (dsers.com) is the official Oberlo successor endorsed by Shopify and AliExpress — it was Oberlo's main competitor and has since grown into the leading AliExpress dropshipping tool with a REST API for product and order management. Spocket (spocket.co) focuses on US and European suppliers with faster shipping times and better product quality than AliExpress. Printful (printful.com) handles print-on-demand dropshipping for custom-branded merchandise. All three provide API access that you can call from Bolt.new API routes.
For Bolt.new developers building a dropshipping application, the architecture is the same regardless of which supplier platform you choose: an API route in Bolt calls the supplier's REST API to browse products and import listings, another route submits new orders for fulfillment, and a Supabase database tracks product catalog and order status. The WebContainer in Bolt handles outbound API calls during development. However, order status webhooks from Printful and Spocket require a deployed URL — these platforms POST fulfillment updates to a URL you register, which the WebContainer cannot receive.
Integration method
Since Oberlo was shut down in June 2022, this guide covers building equivalent dropshipping functionality in Bolt.new using its successors. DSers (the official Oberlo replacement recommended by Shopify) integrates via its REST API. Spocket and Printful both provide comprehensive APIs for product import and order management. All of these integrations use API routes in Bolt with API keys stored in .env — the same pattern Oberlo would have required.
Prerequisites
- An account on at least one active dropshipping platform: Printful (printful.com), Spocket (spocket.co), or DSers (dsers.com)
- An API key from your chosen platform (Printful API key from printful.com/store/design-maker, Spocket access token from the developer settings)
- A Bolt.new project with Next.js for API routes and Supabase for order management
- An understanding that Oberlo no longer exists — any Oberlo API code will not work and must be replaced
- A deployed URL on Netlify or Vercel for registering fulfillment webhook URLs (required for automatic order status updates)
Step-by-step guide
Understand Why Oberlo Is Gone and Choose an Alternative
Understand Why Oberlo Is Gone and Choose an Alternative
Oberlo was shut down on June 15, 2022. Shopify gave users 30 days notice to migrate to alternative tools. After the shutdown date, all Oberlo API endpoints, webhook URLs, and the Oberlo app itself stopped functioning entirely. Any code in GitHub repositories, npm packages named 'oberlo-api', or tutorials describing Oberlo API integration were written before June 2022 and cannot be used to build a working integration. There is no Oberlo API endpoint to call and no Oberlo SDK to install. When you search for Oberlo integration code, you will find deprecated repositories that return 404 errors. The official Shopify migration guide directed users to DSers, which is an Oberlo-like tool built as a Shopify app with API access. If your intended use case is AliExpress dropshipping, DSers is the most direct replacement. If you want US and European suppliers with faster 2-5 day shipping, Spocket is the better choice. If you are building print-on-demand (custom-branded products), Printful is the standard choice and has the most comprehensive API. For this guide, the steps focus on Printful because it has the most developer-friendly API, clear documentation, and does not require being a Shopify merchant — you can build standalone dropshipping stores with Printful's API directly in Bolt without any Shopify dependency.
Pro tip: If you need AliExpress-style dropshipping, use DSers (dsers.com) which is Shopify's recommended Oberlo replacement. For US/EU suppliers with faster shipping, use Spocket. For custom merchandise, use Printful. All three are active and have working APIs as of 2026.
Expected result: You understand that Oberlo is deprecated and have chosen an active alternative (Printful, Spocket, or DSers) based on your dropshipping use case.
Set Up Printful API Access
Set Up Printful API Access
Printful is a print-on-demand dropshipping platform where you design custom products (apparel, home goods, accessories) and they manufacture, pack, and ship each order as it comes in. Printful's API lets you browse their product catalog, create product listings, submit orders for fulfillment, and track shipment status. Unlike Oberlo, Printful does not require a Shopify account — you can integrate directly via API. To get API access, create a free Printful account at printful.com. After signing up, navigate to Dashboard → Settings → Stores and create a new store (choose API platform if you are not connecting to Shopify, WooCommerce, or another specific platform). From your store settings, click Manage under API Access to generate an API key. The API key is a long alphanumeric string. Copy it immediately. Printful uses Bearer token authentication: include Authorization: Bearer YOUR_API_KEY in every API request header. The Printful API v2 base URL is https://api.printful.com. Authentication works for all endpoints: browsing the product catalog (/v2/catalog-products), managing your store's product listings, and submitting orders for fulfillment. During development in Bolt's WebContainer, all outbound calls to Printful's API work without any special configuration — product catalog calls return real data immediately. Create a .env entry for PRINTFUL_API_KEY and set up a lib/printful.ts helper.
Set up Printful API integration. Add PRINTFUL_API_KEY to .env with a placeholder. Create lib/printful.ts that exports an async function callPrintful(path: string, options?: RequestInit) which fetches https://api.printful.com{path} with Authorization: Bearer {PRINTFUL_API_KEY} header and Content-Type: application/json. Returns the parsed JSON response body. Throw an error if the response is not ok, including the Printful error message from the response body. Also export a PrintfulProduct type with id, name, description, and thumbnail_url.
Paste this in Bolt.new chat
1// lib/printful.ts2export interface PrintfulProduct {3 id: number;4 name: string;5 description: string;6 thumbnail_url: string;7 variants_count: number;8 currency: string;9}1011export interface PrintfulVariant {12 id: number;13 name: string;14 price: string;15 retail_price: string;16 size: string;17 color: string;18 in_stock: boolean;19}2021export async function callPrintful(path: string, options?: RequestInit) {22 const response = await fetch(`https://api.printful.com${path}`, {23 ...options,24 headers: {25 Authorization: `Bearer ${process.env.PRINTFUL_API_KEY}`,26 'Content-Type': 'application/json',27 ...options?.headers,28 },29 });3031 const data = await response.json();3233 if (!response.ok) {34 throw new Error(35 data?.error?.message || `Printful API error: ${response.status}`36 );37 }3839 return data;40}Pro tip: Printful has two API versions: the legacy v1 (no /v2 prefix) and the newer v2 (/v2/). Some tutorials still show v1 endpoints. Use v2 for new integrations — it has better pagination, clearer error messages, and active development.
Expected result: PRINTFUL_API_KEY is in .env and lib/printful.ts provides a typed utility for all Printful API calls. Test by calling callPrintful('/v2/catalog-categories') in an API route.
Browse and Import Products from the Printful Catalog
Browse and Import Products from the Printful Catalog
Printful's product catalog contains hundreds of blank products that can be customized with print-on-demand designs. Use the /v2/catalog-products endpoint to browse available products with filtering by category. Each catalog product has a unique ID, a name, a thumbnail, and a list of variants (size/color combinations). To import a product into your store, you create a sync product — a product in your Printful store account that links a catalog product with your design files and your retail pricing. For a Bolt-based dropshipping store that does not use Printful's design tools but wants to sell Printful products, the typical flow is: browse the catalog to find products, display them in your Bolt UI, let users add them to the store, and then use Printful's sync product API to register the import. Store the Printful product ID and variant details in your Supabase products table so your store UI can display them. When the customer places an order and provides their shipping address, you create a Printful order using the stored variant IDs. Building this flow in Bolt requires two API routes: one for fetching catalog products (GET) and one for creating sync products or storing the import in Supabase. The catalog fetch works in Bolt's WebContainer during development — it is a straightforward outbound GET request.
Create an API route at /api/printful/catalog that fetches the first 20 products from Printful's catalog: GET /v2/catalog-products?limit=20. Map each product to { id, name, thumbnail_url, minPrice: 'calculated from variants' }. Return as JSON array. Build a /products/import page that displays these catalog products in a grid with name, thumbnail, and 'Add to Store' button. Clicking 'Add to Store' POSTs to /api/printful/import which inserts the product into my Supabase store_products table with columns: id, printful_id, name, thumbnail_url, retail_price, status ('draft'). Show a success toast on import.
Paste this in Bolt.new chat
1// app/api/printful/catalog/route.ts2import { NextResponse } from 'next/server';3import { callPrintful } from '@/lib/printful';45export async function GET() {6 try {7 const data = await callPrintful('/v2/catalog-products?limit=20&status=active');89 const products = (data.result || data.data || []).map((product: Record<string, unknown>) => ({10 id: product.id,11 name: product.name,12 thumbnail_url: product.thumbnail_url,13 description: product.description || '',14 }));1516 return NextResponse.json({ products });17 } catch (error) {18 const message = error instanceof Error ? error.message : 'Failed to fetch Printful catalog';19 return NextResponse.json({ error: message }, { status: 500 });20 }21}Pro tip: The Printful catalog has 300+ products. Add category filtering by appending ?category_id=X to the catalog endpoint to show only specific product types. Category IDs are available at GET /v2/catalog-categories.
Expected result: The /products/import page displays Printful catalog products with thumbnails. Clicking 'Add to Store' saves the product to Supabase and shows a success message.
Submit Orders to Printful for Fulfillment
Submit Orders to Printful for Fulfillment
When a customer completes a purchase in your Bolt store, you need to submit an order to Printful for fulfillment. Printful will manufacture the product and ship it directly to the customer. The Printful order creation endpoint is POST /v2/orders. The order body requires: recipient (name, address, city, state_code, country_code, zip, email, phone), items (array of sync variant IDs or catalog variant IDs with quantity), and optionally retail_costs for pass-through pricing. Printful returns an order ID and estimated shipping cost. The order initially enters a draft state — you confirm it by calling POST /v2/orders/{id}/confirm, which triggers actual production. Consider adding a confirmation step in your workflow for order review before confirming. After confirmation, Printful processes the order and ships it. Tracking information becomes available via the Printful order status endpoint GET /v2/orders/{id}. For automatic tracking updates, Printful supports webhooks — POST shipping notifications to a URL you register in your Printful store settings. As with all incoming webhooks, the registered URL must be a deployed production URL — the WebContainer cannot receive these incoming POST requests from Printful's servers. Deploy to Netlify or Vercel first, then register the webhook URL in Printful's Dashboard → Settings → Webhooks.
Create an API route at /api/printful/orders that accepts POST with: variantId (Printful variant ID), quantity (number), recipient (object with name, address1, city, state_code, country_code, zip, email). Call Printful POST /v2/orders with the items array (variant_id, quantity, retail_price as string) and recipient. After creating the draft order, automatically confirm it by calling POST /v2/orders/{id}/confirm. Store the Printful order ID, status, and estimated ship date in my Supabase orders table linked to the customer's Bolt order ID. Return the Printful order ID and tracking URL when available.
Paste this in Bolt.new chat
1// app/api/printful/orders/route.ts2import { NextRequest, NextResponse } from 'next/server';3import { callPrintful } from '@/lib/printful';4import { createClient } from '@supabase/supabase-js';56const supabase = createClient(7 process.env.NEXT_PUBLIC_SUPABASE_URL!,8 process.env.SUPABASE_SERVICE_ROLE_KEY!9);1011export async function POST(request: NextRequest) {12 const { variantId, quantity, recipient, boltOrderId, retailPrice } = await request.json();1314 try {15 // Create Printful draft order16 const order = await callPrintful('/v2/orders', {17 method: 'POST',18 body: JSON.stringify({19 recipient,20 items: [{ variant_id: variantId, quantity, retail_price: retailPrice?.toString() }],21 }),22 });2324 const printfulOrderId = order.result?.id || order.id;2526 // Confirm the order to start production27 await callPrintful(`/v2/orders/${printfulOrderId}/confirm`, { method: 'POST' });2829 // Store in Supabase30 await supabase.from('fulfillment_orders').insert({31 bolt_order_id: boltOrderId,32 printful_order_id: printfulOrderId,33 status: 'confirmed',34 supplier: 'printful',35 });3637 return NextResponse.json({ printfulOrderId, status: 'confirmed' });38 } catch (error) {39 const message = error instanceof Error ? error.message : 'Order submission failed';40 return NextResponse.json({ error: message }, { status: 500 });41 }42}Pro tip: Printful orders start as drafts. Calling /confirm triggers actual production and charges your Printful billing. In staging, skip the confirm call and manually cancel draft orders in the Printful Dashboard to avoid charges during testing.
Expected result: POST to /api/printful/orders creates a confirmed Printful order. The order appears in your Printful Dashboard under Orders and the order ID is stored in Supabase.
Deploy and Set Up Fulfillment Webhooks
Deploy and Set Up Fulfillment Webhooks
Your Bolt dropshipping app works in the WebContainer for all outbound operations — product catalog browsing, order submission, and status polling. The only feature that requires deployment is Printful's webhook notifications, which POST order status updates (order shipped, tracking number available) to your registered webhook URL. These incoming POST requests from Printful cannot reach the WebContainer. Deploy your Bolt app to Netlify or Vercel by connecting your GitHub repository. Set your environment variables in the hosting dashboard: PRINTFUL_API_KEY, NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, and SUPABASE_SERVICE_ROLE_KEY. After deployment, create a webhook handler at /api/printful/webhook that receives Printful order events. In your Printful Dashboard, navigate to Settings → Webhooks and add your deployed URL (https://your-app.netlify.app/api/printful/webhook). Select relevant events: order_updated, package_shipped, package_delivered. Printful includes an X-Printful-Signature header for webhook verification — validate it using HMAC-SHA256 with your webhook key. When a package ships, Printful sends the tracking number and carrier, which you can store in Supabase and email to the customer.
Create a webhook handler at /api/printful/webhook that accepts POST requests from Printful. Parse the event type from the body. For 'package_shipped' events, extract: order_id, carrier, tracking_number, tracking_url. Update the corresponding row in my Supabase fulfillment_orders table: set status='shipped', tracking_number, tracking_url. Return HTTP 200. For 'order_updated' events, update the order status. Log the event type and order ID for debugging. Note: this webhook will only work on the deployed URL, not in Bolt's WebContainer preview.
Paste this in Bolt.new chat
1// app/api/printful/webhook/route.ts2import { NextRequest, NextResponse } from 'next/server';3import { createClient } from '@supabase/supabase-js';45const supabase = createClient(6 process.env.NEXT_PUBLIC_SUPABASE_URL!,7 process.env.SUPABASE_SERVICE_ROLE_KEY!8);910export async function POST(request: NextRequest) {11 const payload = await request.json();12 const eventType = payload.type;13 const orderData = payload.data?.order;1415 console.log(`Printful webhook: ${eventType}`, orderData?.id);1617 if (eventType === 'package_shipped' && orderData) {18 const shipment = orderData.shipments?.[0];19 await supabase20 .from('fulfillment_orders')21 .update({22 status: 'shipped',23 tracking_number: shipment?.tracking_number || '',24 tracking_url: shipment?.tracking_url || '',25 shipped_at: new Date().toISOString(),26 })27 .eq('printful_order_id', orderData.id);28 } else if (eventType === 'order_updated' && orderData) {29 await supabase30 .from('fulfillment_orders')31 .update({ status: orderData.status })32 .eq('printful_order_id', orderData.id);33 }3435 return NextResponse.json({ received: true });36}Pro tip: Printful webhook events will only fire to your deployed URL — never to the WebContainer. Register the webhook in Printful Dashboard after deploying, using your production domain.
Expected result: After deploying and registering the Printful webhook URL, order shipment events trigger automatic updates to your Supabase fulfillment_orders table with tracking information.
Common use cases
Print-on-Demand Product Catalog with Printful
Build a custom merchandise store that sells branded products (t-shirts, mugs, phone cases) fulfilled by Printful. Browse Printful's product catalog, import products to your Bolt-powered store, and submit new orders to Printful when a customer purchases. Printful prints the item and ships it directly to the customer with your branding.
Build a product catalog page that uses Printful's API. Create an API route at /api/printful/products that fetches product variants from the Printful catalog API at https://api.printful.com/products using my PRINTFUL_API_KEY. Return an array of products with name, thumbnail_url, and price range. Show products in a 3-column grid with an 'Import to Store' button. When clicked, POST to /api/printful/import-product with the productId which saves the product details to my Supabase products table. The Printful API requires a Bearer token Authorization header.
Copy this prompt to try it in Bolt.new
Order Fulfillment Integration with Spocket
Connect a Bolt-powered storefront to Spocket to automatically submit customer orders for fulfillment. When a customer completes checkout in your Bolt app, an API route sends the order details to Spocket which routes the order to the supplier for picking, packing, and shipping directly to the customer.
Create an order fulfillment flow using Spocket's API. When a customer places an order in my Bolt app and the payment is confirmed by Stripe, POST to /api/spocket/fulfill-order with the order details (product variant IDs, shipping address, customer name). The route should call Spocket's order creation endpoint using my SPOCKET_API_KEY. Store the Spocket order ID in my Supabase orders table alongside the Bolt order ID. Return the Spocket tracking number when available.
Copy this prompt to try it in Bolt.new
Unified Dropshipping Dashboard
Build a management dashboard that shows all pending and fulfilled dropshipping orders across multiple suppliers. Aggregates Printful and Spocket order statuses into a single view, showing which orders are processing, shipped, or delivered. Includes profit margin calculation based on supplier cost vs. sale price.
Build a dropshipping dashboard at /fulfillment that shows all orders from my Supabase orders table. For each order, display the customer name, product name, supplier (Printful or Spocket), order status, supplier cost, sale price, and profit. Add API routes: /api/printful/order-status and /api/spocket/order-status that sync the latest status from each supplier API. Add a Sync All button that calls both status routes and updates the Supabase orders table. Show total revenue, total supplier costs, and total profit in summary cards at the top.
Copy this prompt to try it in Bolt.new
Troubleshooting
Oberlo API endpoints return 404 or the Oberlo npm package gives module not found errors
Cause: Oberlo was permanently shut down in June 2022. All Oberlo API endpoints, npm packages, and SDKs are no longer maintained or accessible.
Solution: Stop attempting to use any Oberlo-branded API endpoints or packages. Replace your integration with an active alternative: Printful for print-on-demand, Spocket for US/EU dropshipping, or DSers for AliExpress dropshipping. Refer to the steps above for Printful integration code.
Printful order creation returns 'Invalid variant id' or 'Variant not found'
Cause: The variant ID being used is a catalog variant ID instead of a sync variant ID for your store, or the variant ID does not exist in the Printful product catalog.
Solution: Ensure you are using the correct ID type for the endpoint. For orders using catalog products directly (without creating sync products first), use the catalog variant ID from GET /v2/catalog-variants. For orders using your store's sync products, use the sync variant ID from GET /v2/sync/variants. The two ID namespaces are separate and not interchangeable.
Printful webhooks are not triggering after deployment and registration
Cause: The webhook URL was registered pointing to the Bolt WebContainer preview URL (a *.stackblitz.io domain) instead of the deployed production URL, or the deployed app returned a non-200 response during Printful's webhook verification test.
Solution: In Printful Dashboard → Settings → Webhooks, verify the registered URL uses your Netlify or Vercel domain (e.g., https://your-app.netlify.app/api/printful/webhook). Use Printful's webhook test button to send a test event and check what response code your handler returns. Ensure the handler always returns HTTP 200.
Best practices
- Be transparent with users that Oberlo no longer exists — redirect anyone searching for Oberlo to active alternatives like DSers, Spocket, or Printful
- Store all supplier order IDs (Printful, Spocket, or DSers) in your Supabase orders table alongside your internal order IDs for cross-reference and debugging
- Never confirm Printful draft orders automatically in development — this triggers real charges. Only auto-confirm in production after payment is verified
- Implement order cancellation before confirmation — give yourself a review window to catch address errors or inventory issues before Printful starts production
- Calculate and display profit margins in your dashboard: sale price minus supplier cost and shipping gives the actual profit per order
- Register separate Printful API keys for development and production stores to prevent test orders from appearing in your live fulfillment queue
- Deploy to test webhooks before going live — order status updates from Printful only reach your registered webhook URL, not the Bolt WebContainer preview
Alternatives
AliExpress API is the direct source for the dropshipping products that Oberlo used — integrate with AliExpress directly for product sourcing without a middleman tool.
Spocket offers US and EU-based suppliers with 2-5 day shipping, higher product quality than AliExpress, and a REST API for product import and order management.
Printful specializes in print-on-demand custom merchandise with its own production facilities, offering predictable quality and a comprehensive API for product and order management.
eBay's API allows product listing and order management for marketplace selling — an alternative channel for the products you would have sold through Oberlo's dropshipping workflow.
Frequently asked questions
Is Oberlo still available in 2026?
No. Oberlo was permanently shut down by Shopify on June 15, 2022. The Oberlo app, API, and all associated services are offline and will not return. Shopify's official recommended replacement is DSers for AliExpress dropshipping. Spocket and Printful are popular alternatives for US/EU suppliers and print-on-demand respectively.
What is the easiest Oberlo replacement to integrate with Bolt.new?
Printful has the most developer-friendly API and the clearest documentation for standalone integrations that do not require a Shopify account. Their REST API uses simple Bearer token authentication and covers the full product-to-fulfillment workflow. Printful is ideal for print-on-demand custom merchandise. For AliExpress-style general dropshipping, DSers is Shopify's recommended replacement but requires a Shopify store. Spocket has a REST API suitable for direct integration from Bolt for US/EU supplier dropshipping.
Can I fulfill Printful orders from Bolt's WebContainer preview?
Creating orders and browsing the product catalog works in the WebContainer during development — these are outbound API calls. However, Printful's webhook notifications (shipment updates, tracking numbers) require a deployed URL because they are incoming POST requests to your server. Build and test the product catalog and order creation in the WebContainer, then deploy to Netlify or Vercel before testing the webhook-driven tracking update flow.
Do I need a Shopify account to use Printful or Spocket?
No. Both Printful and Spocket can be used via their direct APIs without connecting to a Shopify store. For Printful, create a standalone store account in their dashboard and use the API key for direct integration. Spocket also allows direct API access independent of e-commerce platforms. DSers, on the other hand, is primarily designed as a Shopify app and integrating it without Shopify requires more custom development.
How do I migrate existing Oberlo data if I was using it before shutdown?
Oberlo exported user data (product lists and order history) before the June 2022 shutdown. If you have that export as a CSV, you can import the product data into DSers (Shopify's recommended successor) or manually recreate products in Printful or Spocket. New product catalogs need to be rebuilt from the supplier platforms — Oberlo no longer provides access to its archived data.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation