Skip to content

BigCommerce

Bulk AI product photography and descriptions for BigCommerce stores, built on the V3 Catalog API and the FOTOhub Commerce Bridge.

What it does

  • Bulk product photos — filter your catalog, pick a preset, run one job
  • AI descriptions in 6 tones and 3 languages, including SEO page title and meta description
  • Draft-first review — results are held as metafields until you approve them
  • Variant images for products with options
  • Adaptive rate limiting driven by the headers BigCommerce returns, not a fixed delay
  • Scheduled jobs for recurring catalog work

Requirements

StoreAny BigCommerce plan with API account access
Node.js20 or newer
FOTOhubAn API key from fotohub.app/console

Creating a store API account

  1. In your BigCommerce control panel go to Settings → API → Store-level API accounts
  2. Create API account, type V2/V3 API token
  3. Grant these OAuth scopes:
ScopeAccessWhy
ProductsmodifyRead the catalog, write descriptions, attach images
Product imagesmodifyIncluded in the Products scope on current API versions
  1. Save and copy the Access Token and Store Hash — the token is shown only once

Least privilege

Products is the only scope the app needs. Do not grant orders, customers or payments.

Installation

bash
git clone https://github.com/fotohubapp/bigcommerce-app.git
cd bigcommerce-app
npm install
cp .env.example .env
# fill in .env
npm run build
npm start

The admin UI is served at PUBLIC_URL (default http://localhost:3000).

Environment variables

VariableRequiredDescription
BC_STORE_HASHyesStore hash from your API account
BC_ACCESS_TOKENyesAccess token from your API account
FOTOHUB_API_KEYyesYour fh_live_ key
FOTOHUB_CONFIG_SECRETyesEncrypts stored credentials on disk
FOTOHUB_API_ROOTnoAPI base, defaults to https://apis.fotohub.app
PUBLIC_URLnoPublic address of this app, used for the webhook URL
HOST / PORTnoListen address, defaults to 127.0.0.1:3000
ALLOWED_HOSTSnoHost allowlist when running behind a proxy
TRUST_PROXYnoSet when terminating TLS upstream, so client IPs are read correctly
SCHEDULER_ENABLEDnoEnable recurring jobs
FOTOHUB_IMAGE_HOSTSnoExtra hosts allowed as image sources
LOG_LEVELnodebug, info, warn, error

FOTOHUB_CONFIG_SECRET

Credentials are encrypted with this secret. Losing or changing it means reconnecting the store. Set it once and keep it with your other deployment secrets.

Connecting the store

  1. Open the app
  2. Enter your FOTOhub API key — Validate shows your live credit balance
  3. Enter the store hash and access token
  4. Connect — the app registers a connection with the Commerce Bridge and stores the webhook secret

Test connection in Settings verifies both BigCommerce and FOTOhub in one call.

Screens

ScreenPurpose
DashboardCredits, active jobs, pending drafts, products missing descriptions
Product photosBulk job wizard for images
DescriptionsWizard for copy: title, descriptions, SEO meta, alt text
JobsProgress with per-item detail and retry
DraftsReview queue with before/after and text diff
PresetsShared preset library
SchedulesRecurring jobs
SettingsCredentials, defaults, connection health
MCPClaude Desktop and Cursor configuration

Selecting products

The product table reads the V3 catalog with filters for:

  • Keyword search
  • Category and brand
  • Missing description
  • Image count below a threshold
  • Availability and visibility

Paging uses BigCommerce cursors, and Select all matching covers the whole filtered set rather than the visible page.

Cost preflight

Before a job runs, the wizard calls the estimate endpoint and shows "N products × M images = X credits, you have Y". Submission is blocked when your balance is short, so a run never dies partway through the catalog.

Reviewing drafts

Results are stored as metafields in the fotohub namespace rather than written to products.

  • Images — before/after comparison slider with keyboard support
  • Copy — old and new text side by side with word-level diff
  • Approve — writes to BigCommerce: images attached via remote image_url, copy to description, page_title and meta_description, alt text to the image description
  • Reject — removes the draft metafield

Approval is transactional: the write to BigCommerce happens before the draft is marked approved, so a network failure cannot leave a draft marked applied when it was not. Drafts are deduplicated on the bridge item ID, so re-importing the same result twice will not double-apply it.

FAQ blocks and JSON-LD structured data, when generated, are stored as metafields you can render in your theme.

Image attachment

BigCommerce fetches remote images itself, so the app passes the generated image URL to POST /catalog/products/{id}/images rather than proxying bytes. That keeps approval fast even for large batches. Source URLs are validated against an allowlist before being sent.

Rate limiting

BigCommerce returns X-Rate-Limit-Requests-Left and X-Rate-Limit-Time-Reset-Ms on every response. The client reads those and throttles adaptively instead of sleeping a fixed amount, so it uses the headroom your plan actually has and backs off when it runs low. 429 responses are retried with exponential backoff.

The Commerce Bridge additionally spreads job dispatch so one bulk run cannot saturate your store's allowance — see rate budgets.

Workflows

For automation without the UI, the package exposes typed workflows:

typescript
import { runJob, waitForJob } from "@fotohub/bigcommerce";

// Generate one photo per product for a filtered selection
const handle = await runJob("image_generate", {
  categories: [23],
  missingDescription: false,
}, {
  preset: "electronics-clean",
  model: "seedream-5-0-260128",
  numImages: 1,
});

const result = await waitForJob(handle, {
  onProgress: ({ done, total, failed }) =>
    console.log(`${done}/${total} done, ${failed} failed`),
});

Available job kinds: image_generate, image_edit, bg_remove, bg_replace, upscale, recolor, description, alt_text, complete_listing. Costs and options are documented in the Commerce Bridge reference.

Scheduled jobs

With SCHEDULER_ENABLED set, the Schedules screen can run recurring work such as:

  • Generate descriptions for products added since the last run
  • Generate alt text for images that have none

Each schedule carries a per-run credit cap, so a runaway schedule cannot drain your balance. Last-run time and outcome are shown per schedule.

App API

The UI is backed by these endpoints.

EndpointDescription
GET /api/statusApp state and CSRF token
GET /api/settingsConfiguration without secrets
POST /api/connect / POST /api/disconnectStore connection
GET /api/healthBigCommerce and FOTOhub health
GET /api/dashboardDashboard data
GET /api/storeStore info
GET /api/productsCatalog with filters and cursor paging
GET /api/categories / GET /api/brandsTaxonomy for filters
GET /api/presetsPreset library
POST /api/estimateCost preflight
GET, POST /api/jobsList and create jobs
GET /api/batchesGrouped job batches
GET /api/draftsDrafts, approve and reject
GET /api/creditsCredit balance
GET, POST /api/schedulesRecurring jobs
POST /api/webhooksBridge callback receiver
GET /api/mcp-configMCP configuration snippet
POST /api/languageSwitch UI language

Mutating requests require an X-CSRF-Token header with the token from /api/status.

Security

  • The API key and access token are encrypted at rest and never logged or returned by the API
  • Bridge webhooks are verified with HMAC-SHA256 and replay protection
  • CSRF tokens on all mutating requests
  • Per-IP rate limiting on write routes
  • Product-derived strings are escaped before rendering — product titles are attacker-controlled input

Do not expose the app publicly without protection

It holds credentials for your store and your FOTOhub credits. It listens on 127.0.0.1 by default. If you expose it, put HTTPS and authentication in front, and set TRUST_PROXY and ALLOWED_HOSTS.

Managing your catalog from an AI assistant

The MCP screen provides a ready-to-copy configuration:

json
{
  "mcpServers": {
    "fotohub": {
      "url": "https://apis.fotohub.app/mcp/",
      "headers": { "Authorization": "Bearer fh_live_your_api_key" }
    }
  }
}

See the MCP integration guide for the full tool list.

Troubleshooting

SymptomCheck
"Invalid or revoked API key"Key must start with fh_live_ and be active in the console
BigCommerce 401Token or store hash wrong, or the API account was deleted
BigCommerce 403The API account lacks the Products modify scope
No products listedFilters too narrow, or the token lacks catalog access
Job stays queuedCheck /api/health; large jobs are dispatched gradually on purpose
Drafts stay pending after approveThe write to BigCommerce failed — the error is shown on the item
402 insufficient creditsTop up, then use Retry failed only
Image approved but not visibleBigCommerce processes remote images asynchronously; refresh after a moment
429 from BigCommerceExpected under load — the client backs off and continues

Set LOG_LEVEL=debug for verbose logging while diagnosing.