Products

1. Overview

The Firework Product API allows you to manage products and retrieve product-related video content on the Firework platform. This API supports full product lifecycle management — listing, retrieving, creating/updating, and deleting products — as well as retrieving videos tagged with a specific product for PDP (Product Detail Page) integration.

Products are scoped to a business store. You must have a business store before creating products.

The API supports flexible product identification — you can look up products by Firework ID, external product ID, SKU, GTIN, or MPN.

Base URL: https://api.firework.com


2. Authentication

The Firework Product API uses OAuth 2.0 for authentication. Before using this API, you must obtain an access token.

Authentication Methods Supported:

  • Client Credentials: OAuth 2.0 Client Credentials flow for server-to-server authentication (machine-to-machine)

  • User Authentication: Standard OAuth 2.0 user authorization flow

Important: The access token must be from an authenticated user or OAuth app with permission to access the specified business.

Scopes:

Scope
Description

products:read

Read access to products and product videos

products:write

Write access (create, update, delete products). Implicitly grants products:read

📖 Documentation:


3. Endpoint Summary

Endpoint
Method
Scope
Notes

/api/v1/products

POST

products:write

Upsert (create or update) a product

/api/v1/products/{product_id}/videos

GET

products:read

Retrieve videos tagged with a specific product


4. Product Object Reference

The product object is returned by the List, Get, and Upsert endpoints. All IDs are Firework encoded IDs.

4.1. Product Fields

Field
Type
Nullable
Description

id

string

Encoded unique product identifier

external_id

string

External product identifier from your system, or a Firework-generated identifier if omitted on create

name

string

Display name of the product

description

string

Product description (plain text)

currency

string

Three-letter ISO 4217 currency code (e.g., "USD", "EUR")

handle

string

URL handle or slug for the product page

options

string[]

Available option names (e.g., ["color", "size"]). Empty if none

category

string

Product category (free-form text)

hide_price

boolean

Whether to hide price display (default: false)

brand

string

Product brand name

subtitle

string

Product subtitle (max 75 characters)

shipping

string

Shipping information

custom_cta

object

Custom call-to-action button configuration (see Custom CTA Object)

business_store_id

string

Encoded ID of the business store this product belongs to

images

object[]

Array of product images (see Image Object)

units

object[]

Array of product variants/units (see Unit Object)

4.2. Image Object

Field
Type
Nullable
Description

id

string

Encoded unique image identifier

external_id

string

External identifier for the image

url

string

URL of the image

position

integer

Display position (0-indexed), derived from image order during upsert

unit_external_ids

string[]

External IDs of units this image applies to. Empty if global

4.3. Unit Object

Field
Type
Nullable
Description

id

string

Encoded unique unit identifier

external_id

string

External identifier for the unit/variant

name

string

Display name of the unit/variant (e.g., "Red / Large")

price

number

Current price as a number (e.g., 1338.00)

original_price

number

Original price before discount

url

string

Direct URL to purchase this variant

position

integer

Display position (0-indexed). Defaults to 0 if omitted

quantity

integer

Available stock quantity

options

object[]

Option values for this variant (see Unit Option)

sku

string

Stock Keeping Unit

gtin

string

Global Trade Item Number (UPC, EAN, ISBN, etc.)

mpn

string

Manufacturer Part Number

barcode

string

Barcode value

4.4. Unit Option

Field
Type
Nullable
Description

name

string

Option name (e.g., "color")

value

string

Option value (e.g., "Red")

4.5. Custom CTA Object

The custom call-to-action (CTA) object configures an optional action button that appears on the video overlay for this product. A product can have at most one custom CTA. Depending on the value of hide_default_purchase_button, the custom CTA either replaces the default purchase button or augments it (appears alongside it).

Field
Type
Nullable
Description

title

string

One of the supported CTA title keys (see Supported CTA Titles). Must be present together with url.

url

string

Destination URL when the button is clicked. Max 4000 characters. Must be present together with title.

target

string

Link target behavior. One of "_blank" (default), "_self", "iframe".

hide_default_purchase_button

boolean

If true, the custom CTA replaces the default purchase button. If false, both the default purchase button and the custom CTA render. Default: false.

title_translation

string

Response only. Localized display label for the title, derived from the merchant's locale. Not accepted on input.

Supported CTA Titles

Title key
Default English label

order_now

Order Now

buy_now

Buy Now

sign_up

Sign Up

enter_now

Enter Now

enroll_now

Enroll Now >

claim_sample

Claim Sample

take_the_quiz

Take The Quiz

see_recipe

See Recipe

see_more

See More

see_details

See Details

start_the_journey

Start The Journey

personalize_my_blend

Personalize My Blend

order_your_welcome_kit

Order Your Welcome Kit

Display labels are localized per merchant locale via Firework's translation system.

Rendering Behavior

The combination of hide_default_purchase_button and whether title/url are set determines what renders on the video overlay:

hide_default_purchase_button

title / url set?

What renders

false

No

Default purchase button only (1 button)

false

Yes

Default purchase button and custom CTA (2 buttons)

true

Yes

Custom CTA only — the default purchase button is hidden

Validation Rules

  • title and url must both be present together or both be absent. Sending only one of them returns 422 Unprocessable Entity.

  • title must be one of the supported title keys listed above.

  • target must be one of "_blank", "_self", "iframe".

  • url must not exceed 4000 characters.


5. Upsert Product

Create or update a product in a business store. If a product with the same external_id already exists in the specified store, it is updated; otherwise, a new product is created.

Endpoint: POST /api/v1/products Authentication: Bearer token required (OAuth 2.0 Client Credentials) Required Scope: products:write (for OAuth apps) Content Type: application/json

5.1. Request Headers

Name
Description
Required

Authorization

Bearer token: Bearer {ACCESS_TOKEN}

Content-Type

Must be application/json

5.2. Request Body

Product Fields

Field
Type
Required
Default
Description

business_store_id

string

None

Encoded business store ID to create/update the product in

external_id

string

Auto-generated

External product identifier from your system (used for matching). If omitted, a unique ID is auto-generated and the request always creates a new product

name

string

None

Display name of the product

description

string

None

Product description (plain text)

handle

string

None

URL handle or slug for the product page

options

string[]

[]

Available option names (e.g., ["color", "size"])

category

string

None

Product category (free-form text)

hide_price

boolean

false

Whether to hide price display

brand

string

None

Product brand name

subtitle

string

None

Product subtitle (max 75 characters)

shipping

string

None

Shipping information

custom_cta

object

null

Custom call-to-action configuration (see Custom CTA Input). Send null to clear an existing CTA.

product_images

object[]

[]

Array of product images (see Image Input)

product_units

object[]

[]

Array of product variants/units (see Unit Input)

Image Input

Field
Type
Required
Default
Description

external_id

string

None

External identifier for the image

url

string

None

URL of the image

unit_identifiers

string[]

[]

External IDs of units this image applies to

Image position is derived from the image's order in the images array. The request body does not accept a position field for images.

Unit Input

Field
Type
Required
Default
Description

external_id

string

None

External identifier for the unit/variant

name

string

None

Display name of the unit/variant

price

string

None

Current price as a string (e.g., "129.99")

original_price

string

None

Original price before discount (e.g., "149.99")

url

string

None

Direct URL to purchase this variant

quantity

integer

None

Available stock quantity

options

object[]

None

Option values for this variant (pass [] if no options)

sku

string

None

Stock Keeping Unit

gtin

string

None

Global Trade Item Number (UPC, EAN, ISBN, etc.)

mpn

string

None

Manufacturer Part Number

barcode

string

None

Barcode value

Unit position is derived from the unit's order in the product_units array. The request body does not accept a position field for units.

Each unit option object has:

Field
Type
Required
Description

name

string

Option name (e.g., "color")

value

string

Option value (e.g., "Gray")

Custom CTA Input

Optional. If provided, must be an object matching the Custom CTA Object shape.

Field
Type
Required
Default
Description

title

string

None

One of the supported CTA title keys. Must be present together with url.

url

string

None

Destination URL (max 4000 characters). Must be present together with title.

target

string

"_blank"

Link behavior: "_blank", "_self", or "iframe".

hide_default_purchase_button

boolean

false

If true, the custom CTA replaces the default purchase button. See Rendering Behavior.

Update and clearing semantics:

  • To clear an existing CTA, send "custom_cta": null. The embedded CTA is removed from the product.

  • To preserve an existing CTA unchanged, omit custom_cta from the request body entirely.

  • Partial updates are not supported. Because title and url must move together, you cannot update only one of them. Always send the full custom CTA object when modifying it.

Important Update Behavior

  • If units is included in an upsert for an existing product, the existing unit collection is replaced by the provided units array.

  • If images is included in an upsert for an existing product, the existing image collection is replaced by the provided images array.

  • Image-to-unit associations are rebuilt from images[].unit_external_ids against the units included in the same request. To safely update variant images and their associations, send images and units together.

5.3. Upsert Product Response

Success Response: 201 Created

The response returns the full product object as described in the Product Object Reference.

5.4. Upsert Product Error Responses

Status Code
Description

400 Bad Request

Missing required fields or malformed JSON

401 Unauthorized

Invalid or missing authentication token

403 Forbidden

Insufficient scope or no access to the specified business store

404 Not Found

Business store not found

422 Unprocessable Entity

Validation errors (e.g., invalid currency, missing unit fields, malformed nested units or images, invalid custom_cta such as title not in enum, title without url or vice versa, url longer than 4000 characters)

5.5. Examples

CURL Request

Minimal Upsert (product with no variants)


6. List Product Videos

Retrieve videos tagged with a specific product. Designed for PDP (Product Detail Page) integration.

Endpoint: GET /api/v1/products/{product_id}/videos Authentication: Bearer token required Required Scope: products:read (for OAuth apps)

6.1. Request Headers

Name
Description
Required

Authorization

Bearer token: Bearer {ACCESS_TOKEN}

6.2. Path Parameters

Parameter
Type
Required
Description

product_id

string

Product identifier (see Product Identifiers)

6.3. Query Parameters

Parameter
Type
Required
Default
Description

channel_id

string

None

Firework encoded channel ID

business_store_id

string

None

Encoded business store ID for product lookup

before_id

string

None

Cursor for pagination (get entries before this video ID)

since_id

string

None

Cursor for pagination (get entries after this video ID)

page_size

integer

10

Number of videos per page (max: 100)

6.4. List Product Videos Response

Success Response: 200 OK

Field
Type
Nullable
Description

videos

object[]

Array of video objects

paging

object

Pagination information

Video Object

Field
Type
Nullable
Description

id

string

Encoded video ID

caption

string

Video title/caption

description

string

Video description

hashtags

string[]

Array of hashtag strings (empty if none provided)

access

string

Video visibility level ("public", "private", "unlisted")

audio_disabled

boolean

Whether audio is disabled for the video (default: false)

archived_at

string

ISO 8601 timestamp when video was archived

product_ids

string[]

Array of Firework encoded product IDs

custom_fields

object

Custom key-value metadata

thumbnail_url

string

CDN URL for the video thumbnail image (540x960)

display_social_attributions

boolean

Whether social attribution is displayed

external_media

object

Social media source metadata (see External Media Schema)

video_posters

array

Array of video poster images (empty if none). See Video Poster Schema below

hidden

boolean

Whether the video is hidden in the product listing

Video Poster Schema

Field
Type
Nullable
Description

url

string

CDN URL for the poster image

aspect_ratio

string

Aspect ratio (e.g. "9:16", "16:9", "1:1")

format

string

Image format ("jpg", "webp", "gif", "png")

width

integer

Image width in pixels

height

integer

Image height in pixels

Paging Object

Field
Type
Nullable
Description

next

string

URL to fetch the next page of results (null if no more results)

6.5. List Product Videos Error Responses

Status Code
Description

400 Bad Request

Missing channel_id parameter or invalid pagination values

401 Unauthorized

Missing or invalid token

403 Forbidden

Missing products:read scope or channel belongs to other business

404 Not Found

Product or channel not found

Authorization Note: The channel_id must belong to the same business as the authenticated user or OAuth app. Attempting to access a channel from another business returns 403.

6.6. Examples

CURL Request

Example Response

Example Response (Last Page)


7. Pagination

All list endpoints use cursor-based pagination for efficient navigation through large result sets.

How it works:

  • Use before_id to get older entries (descending order by ID)

  • Use since_id to get newer entries (ascending order by ID)

  • Only one of before_id or since_id may be used per request

  • The response includes a paging object with the next URL if more results exist

  • When no more results exist, paging will be an empty object: {}

Pagination Examples


8. Product Identifiers

The product_id path parameter in the Get Product, Delete Product, and List Product Videos endpoints accepts multiple identifier types for flexibility:

  • Firework encoded product ID — The internal Firework product identifier

  • External product ID — Your system's product identifier

  • External product unit ID — Your system's product variant/unit identifier

  • Product unit GTIN — Global Trade Item Number (UPC, EAN, ISBN, etc.)

  • Product unit SKU — Stock Keeping Unit

  • Product unit MPN — Manufacturer Part Number

Product Lookup Rules

  • The system will attempt to resolve the product using each identifier type in sequence

  • If business_store_id is provided, the lookup is scoped to that specific store

  • If business_store_id is omitted, the system uses the first business store of the authenticated business

  • If the product cannot be found using any identifier type, a 404 Not Found is returned

Identifier Examples

Last updated

Was this helpful?