Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with ShipStation

Connect Bolt.new to ShipStation using its REST API with HTTP Basic authentication — just your API key and secret encoded as Base64. Build an API route that fetches orders, creates shipping labels, and shops rates across USPS, UPS, and FedEx. Outbound API calls work in Bolt's WebContainer during development. Webhook notifications for shipment status changes require a deployed URL on Netlify or Vercel.

What you'll learn

  • How to get your ShipStation API key and secret from Account Settings and authenticate with HTTP Basic auth
  • How to build a Next.js API route that fetches orders and filters by status
  • How to request carrier rate quotes across USPS, UPS, and FedEx from a single API call
  • How to create shipping labels programmatically via ShipStation's createLabel endpoint
  • How to configure ShipStation webhooks for real-time shipment status updates after deploying
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate16 min read30 minutesOtherApril 2026RapidDev Engineering Team
TL;DR

Connect Bolt.new to ShipStation using its REST API with HTTP Basic authentication — just your API key and secret encoded as Base64. Build an API route that fetches orders, creates shipping labels, and shops rates across USPS, UPS, and FedEx. Outbound API calls work in Bolt's WebContainer during development. Webhook notifications for shipment status changes require a deployed URL on Netlify or Vercel.

Build a Shipping Management Dashboard with ShipStation and Bolt.new

ShipStation sits at the center of e-commerce fulfillment — it aggregates orders from Shopify, WooCommerce, Amazon, Etsy, and dozens of other channels, lets you rate-shop across carriers in real time, and generates shipping labels with a single API call. Integrating it into a Bolt.new app lets you build custom shipping dashboards, automate label creation workflows, or surface shipping data inside your own branded admin panel without forcing your team to log into another third-party tool.

The ShipStation REST API uses HTTP Basic authentication, which is one of the simplest auth patterns available: you Base64-encode your API key and secret separated by a colon, then send that as the Authorization header. There is no OAuth flow to manage, no token refresh cycle, and no expiry. This simplicity makes it an excellent API to learn with and easy to debug. All credentials must be stored server-side in your .env file and accessed only from Next.js API routes — never from client-side React components.

During Bolt.new development, outbound calls to ShipStation's API endpoints work immediately in the WebContainer. You can fetch orders, shop rates, and test label creation from the preview environment. The only functionality that requires deployment is ShipStation's webhook system, which sends POST requests to your endpoint when order or shipment status changes occur. Since WebContainers cannot receive incoming HTTP connections, you must deploy to Netlify or Vercel and register your webhook URL in ShipStation's settings before webhook events will arrive.

Integration method

Bolt Chat + API Route

ShipStation uses HTTP Basic authentication — your API key and secret are Base64-encoded and sent in the Authorization header. All API calls must be made server-side from a Next.js API route to keep your credentials out of the browser. Bolt.new's WebContainer handles outbound calls to ShipStation's REST API during development. Webhook notifications (shipment status updates, order imports) require a deployed URL since they send incoming POST requests that WebContainers cannot receive.

Prerequisites

  • A ShipStation account with at least one connected carrier (USPS, UPS, or FedEx)
  • A ShipStation API key and secret from Account → Account Settings → API Settings → Generate API Keys
  • A Bolt.new account with a new Next.js project open
  • Products or orders already in ShipStation (or a plan to create them via API) to test against
  • A Netlify account for deployment if you need webhook notifications for shipment status changes

Step-by-step guide

1

Get your ShipStation API credentials and set up authentication

ShipStation uses HTTP Basic authentication — one of the simplest auth schemes in any REST API ecosystem. You need two values: an API key and an API secret, both available from your ShipStation account settings. To generate your credentials: log into ShipStation, click your account name in the top-right corner, then go to Account Settings → API Settings. You will see a section called API Keys. Click Generate API Keys. ShipStation immediately shows you both the API Key (a long alphanumeric string) and the API Secret. Copy both — the secret is shown once. Store them somewhere secure like a password manager before adding them to your project. HTTP Basic authentication requires you to Base64-encode the combination `apiKey:apiSecret` and include it in the Authorization header as `Basic <encoded-string>`. In Node.js, this is straightforward: `Buffer.from('key:secret').toString('base64')`. Alternatively, you can use the native `fetch` without manual encoding by passing the credentials directly in the URL as `https://key:secret@ssapi.shipstation.com/...` — but the explicit header approach is cleaner and easier to debug. The base URL for all ShipStation API calls is `https://ssapi.shipstation.com`. All endpoints use this domain with paths like `/orders`, `/shipments`, `/carriers`, etc. Add both credentials to your .env file as shown below — never commit them to Git or use NEXT_PUBLIC_ prefix.

Bolt.new Prompt

Set up ShipStation API authentication in my Next.js project. Create a .env file with SHIPSTATION_API_KEY=your-api-key and SHIPSTATION_API_SECRET=your-api-secret. Create a lib/shipstation.ts file that exports a shipstationFetch helper function. This function should accept an endpoint (e.g., '/orders') and optional init options, construct the Basic auth header by Base64-encoding SHIPSTATION_API_KEY:SHIPSTATION_API_SECRET from process.env, set Content-Type to application/json, and call https://ssapi.shipstation.com/{endpoint}. Return the parsed JSON response. Add TypeScript types. Export the base URL as a constant.

Paste this in Bolt.new chat

lib/shipstation.ts
1// lib/shipstation.ts
2const BASE_URL = 'https://ssapi.shipstation.com';
3
4function getAuthHeader(): string {
5 const key = process.env.SHIPSTATION_API_KEY;
6 const secret = process.env.SHIPSTATION_API_SECRET;
7 if (!key || !secret) {
8 throw new Error('SHIPSTATION_API_KEY and SHIPSTATION_API_SECRET must be set');
9 }
10 return 'Basic ' + Buffer.from(`${key}:${secret}`).toString('base64');
11}
12
13export async function shipstationFetch<T = unknown>(
14 endpoint: string,
15 init: RequestInit = {}
16): Promise<T> {
17 const url = `${BASE_URL}${endpoint.startsWith('/') ? endpoint : '/' + endpoint}`;
18 const response = await fetch(url, {
19 ...init,
20 headers: {
21 'Authorization': getAuthHeader(),
22 'Content-Type': 'application/json',
23 ...init.headers,
24 },
25 });
26
27 if (!response.ok) {
28 const errorText = await response.text();
29 throw new Error(`ShipStation API error ${response.status}: ${errorText}`);
30 }
31
32 return response.json() as Promise<T>;
33}

Pro tip: ShipStation enforces a rate limit of 40 API calls per minute. If you are building a dashboard that polls frequently, add caching with a 60-second TTL using Next.js route segment config (`export const revalidate = 60`) or an in-memory cache to avoid hitting the limit during development.

Expected result: A configured ShipStation authentication helper in lib/shipstation.ts and credentials stored in .env, ready for use in API routes.

2

Fetch and display orders from ShipStation

The ShipStation orders endpoint (`GET /orders`) returns paginated order data including recipient details, line items, weight, and current order status. You will build an API route that fetches orders filtered by status and passes them to a React dashboard component. ShipStation orders have several status values you will encounter: `awaiting_payment` (order received, payment not confirmed), `awaiting_shipment` (paid and ready to fulfill — this is the most important queue for fulfillment teams), `shipped` (label created and tracking number assigned), `on_hold`, and `cancelled`. Most fulfillment dashboards focus on `awaiting_shipment` orders. The endpoint supports extensive filtering via query parameters: `orderStatus`, `orderDateStart`, `orderDateEnd`, `storeId` (to filter by sales channel), `sortBy` (OrderDate, ModifyDate), and `sortDir` (ASC or DESC). For pagination, use `page` (1-indexed) and `pageSize` (max 500). A typical dashboard request fetches the first page of `awaiting_shipment` orders sorted by oldest first. The response JSON includes `orders` (array), `total` (total matching orders across all pages), `page`, and `pages`. Build your API route to pass through the full response so your frontend can show pagination controls when there are many orders. In the React component, display the key fields your team needs at a glance: order number, customer name, shipping destination state/country, order total, and item count. A well-organized fulfillment table dramatically speeds up pick-and-pack workflows compared to the default ShipStation interface.

Bolt.new Prompt

Create an API route at app/api/shipstation/orders/route.ts. Accept GET requests with optional query params: status (default 'awaiting_shipment'), page (default 1), pageSize (default 50). Call shipstationFetch from lib/shipstation.ts to GET /orders with those query params. Return the orders array and pagination info. Then create a React component at components/ShipStationOrders.tsx that calls this API route on mount, shows a loading state, and renders the orders in a table with columns: Order Number, Customer Name, Destination (city, state), Items, Order Total, Order Date. Add a status filter dropdown at the top.

Paste this in Bolt.new chat

app/api/shipstation/orders/route.ts
1// app/api/shipstation/orders/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { shipstationFetch } from '@/lib/shipstation';
4
5interface ShipStationOrdersResponse {
6 orders: unknown[];
7 total: number;
8 page: number;
9 pages: number;
10}
11
12export async function GET(request: NextRequest) {
13 const { searchParams } = new URL(request.url);
14 const status = searchParams.get('status') ?? 'awaiting_shipment';
15 const page = searchParams.get('page') ?? '1';
16 const pageSize = searchParams.get('pageSize') ?? '50';
17
18 const params = new URLSearchParams({
19 orderStatus: status,
20 page,
21 pageSize,
22 sortBy: 'OrderDate',
23 sortDir: 'ASC',
24 });
25
26 const data = await shipstationFetch<ShipStationOrdersResponse>(
27 `/orders?${params.toString()}`
28 );
29
30 return NextResponse.json(data);
31}

Pro tip: ShipStation's API returns all order details including line items in a single call — no need for secondary lookups per order. This makes it very efficient for dashboard views: one API call gives you everything needed to render a full orders table.

Expected result: An API route that returns paginated ShipStation orders filtered by status, and a dashboard table displaying pending shipments with key fulfillment details.

3

Shop carrier rates and create shipping labels

Rate shopping and label creation are the two most valuable ShipStation API capabilities. Instead of logging into ShipStation and manually comparing carrier options, your app can present rates automatically and let users select one to instantly generate a label. For rate shopping, the endpoint is `POST /carriers/listrates`. The request body requires `carrierCode` (or use the special value `stamps_com` for USPS), `serviceCode` (optional — omit to get all services), `fromPostalCode`, `toPostalCode`, `toCountry` (ISO 2-letter code), `weight` (object with `value` and `units` — use `ounces`), and optionally `dimensions` (length, width, height in inches). The response is an array of rate objects, each with `carrierCode`, `serviceCode`, `serviceName`, `shipDate`, `deliveryDays`, and `shipmentCost`. Sort by `shipmentCost` ascending to show cheapest first. For label creation, use `POST /orders/createlabelfororder`. You pass the `orderId` (from the orders list), `carrierCode`, `serviceCode`, and `confirmation` (e.g., `none`, `delivery`, `signature`). ShipStation creates the label in your connected carrier account and returns `shipmentId`, `trackingNumber`, `labelData` (Base64-encoded PDF), and `labelFileToken`. Save the tracking number to your database so you can surface it in order confirmations. Important: calling `createlabelfororder` deducts from your connected carrier account (e.g., Stamps.com credits or UPS account balance) immediately. Use a test carrier or sandbox account during development — ShipStation does not have a separate sandbox environment, so label creation is always live. For rate-only requests (no purchase), ShipStation's rates API does not charge anything — it is a pure quote API.

Bolt.new Prompt

Create two API routes for ShipStation label workflows. First: app/api/shipstation/rates/route.ts that accepts POST with fromPostalCode, toPostalCode, toCountry, weightOz, and optional dimensions (length, width, height). Call shipstationFetch to POST /carriers/listrates requesting rates from all carriers. Return the rates array sorted by shipmentCost ascending. Second: app/api/shipstation/create-label/route.ts that accepts POST with orderId, carrierCode, serviceCode, and confirmation (default 'none'). Call shipstationFetch to POST /orders/createlabelfororder and return trackingNumber and labelData. Add a warning comment that label creation charges the carrier account immediately.

Paste this in Bolt.new chat

app/api/shipstation/rates/route.ts
1// app/api/shipstation/rates/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { shipstationFetch } from '@/lib/shipstation';
4
5interface RateResponse {
6 carrierCode: string;
7 serviceCode: string;
8 serviceName: string;
9 shipDate: string;
10 deliveryDays: number;
11 shipmentCost: number;
12 otherCost: number;
13}
14
15export async function POST(request: NextRequest) {
16 const { fromPostalCode, toPostalCode, toCountry, weightOz, dimensions } =
17 await request.json();
18
19 if (!fromPostalCode || !toPostalCode || !weightOz) {
20 return NextResponse.json(
21 { error: 'fromPostalCode, toPostalCode, and weightOz are required' },
22 { status: 400 }
23 );
24 }
25
26 const body: Record<string, unknown> = {
27 carrierCode: 'stamps_com',
28 fromPostalCode,
29 toPostalCode,
30 toCountry: toCountry ?? 'US',
31 weight: { value: weightOz, units: 'ounces' },
32 };
33
34 if (dimensions) {
35 body.dimensions = {
36 length: dimensions.length,
37 width: dimensions.width,
38 height: dimensions.height,
39 units: 'inches',
40 };
41 }
42
43 const rates = await shipstationFetch<RateResponse[]>('/carriers/listrates', {
44 method: 'POST',
45 body: JSON.stringify(body),
46 });
47
48 const sorted = [...rates].sort((a, b) => a.shipmentCost - b.shipmentCost);
49 return NextResponse.json({ rates: sorted });
50}

Pro tip: ShipStation does not have a sandbox mode — rate quotes are always live but do not charge you. Label creation, however, immediately charges your carrier account. During development, use small orders or create a dedicated development carrier connection with a low balance to avoid unexpected charges.

Expected result: A rate comparison API that returns carrier rates sorted by cost, and a label creation API that generates shipping labels and returns tracking numbers.

4

Deploy to Netlify and configure ShipStation webhooks

During development in Bolt.new's WebContainer, all outbound calls to ShipStation work perfectly — you can fetch orders, shop rates, and create labels without any issues. The WebContainer limitation only applies to incoming connections, which affects ShipStation's webhook system. ShipStation webhooks send POST requests to your registered URL when events occur: `ORDER_NOTIFY` (new order arrives), `SHIP_NOTIFY` (shipment created with tracking), `ITEM_ORDER_NOTIFY`, and several others. These real-time notifications are what allow your app to react to fulfillment events — updating order status in your database, sending shipping confirmation emails to customers, or updating inventory levels — without polling the ShipStation API every few minutes. To deploy: click Deploy in Bolt.new and connect to Netlify. After deployment, go to your Netlify dashboard → Site Configuration → Environment Variables and add `SHIPSTATION_API_KEY`, `SHIPSTATION_API_SECRET`, and any other variables you have in .env. Trigger a redeploy. To configure webhooks in ShipStation: go to Account → Account Settings → Webhooks → Add Webhook. Enter your Netlify URL for the webhook endpoint (e.g., `https://your-app.netlify.app/api/shipstation/webhook`), select the event type (`SHIP_NOTIFY` is most commonly needed), choose the store to monitor, and save. ShipStation sends a test POST immediately — your handler should return 200. Webhook payloads from ShipStation include a `resource_url` field rather than the full event data — you must make a second API call to that URL to get the actual shipment or order details. This two-step pattern is intentional and reduces payload size for high-volume accounts.

Bolt.new Prompt

Create a ShipStation webhook handler at app/api/shipstation/webhook/route.ts. Accept POST requests. Parse the JSON body which has a resource_type (e.g., 'SHIP_NOTIFY') and resource_url. For SHIP_NOTIFY events, call shipstationFetch using the resource_url to get the shipment details. Log the trackingNumber and orderKey. Always return 200 with { received: true }. Add a comment explaining that ShipStation webhooks cannot be received in Bolt's WebContainer preview — they require a deployed Netlify URL. Also create a netlify.toml with the Next.js build plugin configuration.

Paste this in Bolt.new chat

app/api/shipstation/webhook/route.ts
1// app/api/shipstation/webhook/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { shipstationFetch } from '@/lib/shipstation';
4
5interface ShipStationWebhookBody {
6 resource_url: string;
7 resource_type: string;
8}
9
10interface ShipmentResource {
11 shipments: Array<{
12 shipmentId: number;
13 orderId: number;
14 orderKey: string;
15 trackingNumber: string;
16 carrierCode: string;
17 serviceCode: string;
18 shipDate: string;
19 shipmentCost: number;
20 }>;
21}
22
23// NOTE: ShipStation webhooks require a publicly deployed URL.
24// During Bolt.new WebContainer development, incoming webhooks cannot
25// be received. Deploy to Netlify first, then register the webhook URL
26// in ShipStation Account Settings → Webhooks.
27export async function POST(request: NextRequest) {
28 const body: ShipStationWebhookBody = await request.json();
29 const { resource_type, resource_url } = body;
30
31 if (resource_type === 'SHIP_NOTIFY' && resource_url) {
32 // ShipStation sends resource_url — we must fetch the actual data
33 const endpoint = resource_url.replace('https://ssapi.shipstation.com', '');
34 const data = await shipstationFetch<ShipmentResource>(endpoint);
35
36 for (const shipment of data.shipments ?? []) {
37 console.log(
38 `Shipment created: order ${shipment.orderKey}, ` +
39 `tracking ${shipment.trackingNumber} via ${shipment.carrierCode}`
40 );
41 // TODO: Update your database and send tracking email to customer
42 }
43 }
44
45 // Always return 200 — ShipStation retries on non-200 responses
46 return NextResponse.json({ received: true });
47}

Pro tip: ShipStation retries failed webhook deliveries (non-200 responses) up to 10 times over 24 hours. Always return 200 from your handler even if internal processing fails. Log errors internally and process webhook data asynchronously to avoid timeouts.

Expected result: A deployed app on Netlify with a webhook handler that receives ShipStation shipment notifications and logs tracking numbers for further processing.

Common use cases

Shipping Rate Comparison Dashboard

Build a dashboard that accepts order dimensions and destination, then queries ShipStation for rate quotes across all connected carriers in one call. Display USPS, UPS, and FedEx rates side by side so your fulfillment team can always pick the cheapest or fastest option at a glance.

Bolt.new Prompt

Build a shipping rate comparison tool in my Next.js app. Create an API route at /api/shipstation/rates that accepts POST with weight (oz), dimensions (length, width, height in inches), fromZip, toZip, and toCountry. Call ShipStation's carrier/listrates endpoint using HTTP Basic auth with SHIPSTATION_API_KEY and SHIPSTATION_API_SECRET from process.env. Return the rates array sorted by shipmentCost ascending. Create a React component with a form for these inputs and a results table showing carrier name, service name, days, and cost. Show a loading spinner during the request.

Copy this prompt to try it in Bolt.new

Order Fulfillment Queue

Create an internal fulfillment dashboard that pulls all awaiting_shipment orders from ShipStation and displays them in a sortable table. Your fulfillment team can review orders, select a carrier service, and trigger label creation — all from your custom admin interface.

Bolt.new Prompt

Create an order fulfillment dashboard. Build an API route at /api/shipstation/orders that fetches orders from ShipStation with orderStatus=awaiting_shipment using HTTP Basic auth (SHIPSTATION_API_KEY:SHIPSTATION_API_SECRET Base64-encoded). Also create /api/shipstation/create-label that accepts POST with orderId and carrierCode, calls ShipStation's orders/createlabelfororder endpoint, and returns the labelData with trackingNumber and labelUrl. Build a React page with a table of pending orders, a carrier selector per row, and a Create Label button that calls the label endpoint and shows the tracking number on success.

Copy this prompt to try it in Bolt.new

Automated Post-Purchase Label Creation

After a customer completes checkout in your Bolt app, automatically push the order to ShipStation and trigger label creation for pre-configured carrier services. This removes the manual step of logging into ShipStation to process orders.

Bolt.new Prompt

After a successful Stripe payment in my app, automatically create a ShipStation order. Build an API route at /api/shipstation/push-order that accepts POST with customer details (name, address, email), line items (sku, name, quantity, price), and order total. Call ShipStation POST /orders/createorder to create the order, then immediately call POST /orders/createlabelfororder with the returned orderId and a default carrier from SHIPSTATION_DEFAULT_CARRIER env var. Return the trackingNumber and labelUrl to the frontend for display on the confirmation page.

Copy this prompt to try it in Bolt.new

Troubleshooting

API calls return 401 Unauthorized even though credentials appear correct

Cause: HTTP Basic auth requires the credentials to be Base64-encoded as 'apiKey:apiSecret' (colon separator). A common mistake is encoding them separately or swapping key and secret order. Another cause is whitespace or newline characters accidentally included when copying credentials from the ShipStation dashboard.

Solution: Verify your encoding: in Node.js, run Buffer.from('yourkey:yoursecret').toString('base64') in a test script and compare to what your code generates. Also check that SHIPSTATION_API_KEY contains the key (shorter string) and SHIPSTATION_API_SECRET contains the secret (longer string) — they are sometimes confused. Regenerate API keys in Account → Account Settings → API Settings if issues persist.

typescript
1// Quick test in a Node.js script or Bolt terminal
2const key = process.env.SHIPSTATION_API_KEY;
3const secret = process.env.SHIPSTATION_API_SECRET;
4console.log('Auth header:', 'Basic ' + Buffer.from(`${key}:${secret}`).toString('base64'));

Rate quotes return an empty array or 'carrier not found' error

Cause: ShipStation only returns rates for carriers that are connected to your account. If you haven't connected a USPS, UPS, or FedEx account in ShipStation's Carriers settings, the rates API returns nothing for that carrier code.

Solution: In ShipStation, go to Account → Carriers and connect at least one carrier. For USPS, use Stamps.com (built in) with carrierCode 'stamps_com'. For UPS, use carrierCode 'ups'. After connecting a carrier, retry the rates API call. You can also call GET /carriers to list all connected carriers and their codes programmatically.

ShipStation webhooks are not arriving during Bolt.new development

Cause: Bolt.new runs in a WebContainer — a browser-based Node.js runtime that does not have a persistent public URL. ShipStation webhooks send POST requests to your registered endpoint, which requires a publicly accessible server. The Bolt.new preview URL is not reachable by external services.

Solution: Deploy your app to Netlify first (click Deploy in Bolt.new), then register the deployed URL in ShipStation Account Settings → Webhooks. Use your Netlify domain like https://your-app.netlify.app/api/shipstation/webhook. This is a fundamental WebContainer limitation — webhooks always require a deployed environment.

Rate limit errors (429 Too Many Requests) appearing in the API logs

Cause: ShipStation allows 40 API calls per minute. Dashboard components that fetch orders on every render, or polling intervals set too frequently, quickly exhaust this limit — especially during active development when the browser refreshes often.

Solution: Add caching to your API routes using Next.js revalidate config or an in-memory cache. Set the route segment to revalidate every 60 seconds so repeated client requests within the same minute hit the cache instead of ShipStation's API. For dashboards, implement a manual refresh button rather than auto-polling.

typescript
1// app/api/shipstation/orders/route.ts — add at top
2export const revalidate = 60; // Cache for 60 seconds

Best practices

  • Store SHIPSTATION_API_KEY and SHIPSTATION_API_SECRET only in server-side environment variables — never prefix them with NEXT_PUBLIC_ or access them from React components
  • Implement an in-memory or Redis cache for order listings since the ShipStation API has a 40 requests/minute rate limit and dashboard views can trigger many requests
  • Always return HTTP 200 from webhook handlers even when processing fails — ShipStation retries non-200 responses repeatedly, leading to duplicate processing
  • Use the resource_url pattern for webhooks: ShipStation sends only a URL in webhook payloads, not the full data — always make a follow-up GET request to retrieve the actual shipment or order details
  • Test rate shopping before label creation — always get a rate quote first to confirm service availability before calling createlabelfororder, which charges your carrier account immediately
  • Validate required shipping fields (postal codes, country codes, weight) in your API route before calling ShipStation to provide helpful error messages to users instead of forwarding cryptic API errors
  • Use ShipStation's pagination parameters (page and pageSize up to 500) rather than fetching all orders in one call — large stores can have thousands of awaiting_shipment orders
  • Log tracking numbers to your own database immediately after label creation — ShipStation is the system of record for labels, but your app should have a local copy for order confirmation emails and customer-facing tracking pages

Alternatives

Frequently asked questions

Can I use ShipStation's API in Bolt.new without deploying?

Yes, for all outbound API calls. Fetching orders, shopping carrier rates, and creating labels all involve outbound HTTP calls from your Bolt.new API route to ShipStation's servers — these work perfectly in Bolt's WebContainer during development. The only capability that requires deployment is ShipStation webhooks, which send incoming POST requests that WebContainers cannot receive.

Does ShipStation have a sandbox or test environment?

No, ShipStation does not offer a separate sandbox environment. All API calls are made against your live account. Rate quotes are free and non-destructive, but label creation immediately charges your connected carrier account. Use ShipStation's 'Void Label' feature after testing to cancel test labels. Some developers create a second ShipStation account with no carrier balance for pure API testing.

How do I get rates for multiple carriers at once?

The POST /carriers/listrates endpoint accepts a single carrierCode per request. To compare across all carriers, you need to make separate requests for each connected carrier (stamps_com, ups, fedex, etc.) and combine the results. Alternatively, call GET /carriers first to get your list of connected carrier codes, then make parallel rate requests using Promise.all() in your API route.

What ShipStation API authentication method should I use in Bolt.new?

Use HTTP Basic authentication — Base64-encode your API key and secret in the format key:secret and pass it as the Authorization header. The encoding is done with Buffer.from('key:secret').toString('base64') in Node.js. Always do this encoding inside an API route where process.env variables are available server-side, never in client-side React code.

How do I avoid hitting ShipStation's 40 requests/minute rate limit?

Add caching to your API routes using Next.js route segment revalidation (export const revalidate = 60) to serve cached responses for up to 60 seconds. For dashboards that display order counts and status, a 60-second cache is imperceptible to users. Also replace auto-polling with manual refresh buttons where possible, since frequent polling is the most common cause of rate limit errors.

Can ShipStation webhooks be tested locally in Bolt.new?

No — ShipStation webhooks send POST requests to your registered URL, and Bolt.new's WebContainer has no persistent public URL that external services can reach. To test webhooks, deploy your app to Netlify or Vercel, register the deployed URL in ShipStation Account Settings → Webhooks, and trigger a test event. Alternatively, use a tunneling service like ngrok with a locally exported Bolt project.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.