Types

All GraphQL object types the API returns, in alphabetical order.

AmendMediaPlanResult

Fields:

  • adsAdded Int!
  • adsApproved Int!: Ads SET_APPROVAL approved. Ads it skipped as not ready are in notes, with the reason.
  • adsUnapproved Int!: Ads SET_APPROVAL un-approved on purpose. Not counted in approvalsWithdrawn.
  • approvalsWithdrawn Int!: Approved ads this amendment changed, which are no longer approved and need approving again. Tell the person.
  • cardsChanged Int!
  • cardsRemoved Int!
  • notes [String!]!: Not errors, but worth telling the person: operations that changed nothing (e.g. removing a unit already gone, adding one already there), ads SET_APPROVAL skipped as not ready and why, hand-adjusted layouts an edit reset.
  • plan MediaPlan!

AmendPlanResult

Result of amendPlan: counts of updated, added, and removed draft records

Fields:

  • added Int!
  • removed Int!
  • updated Int!

Batch

A unit of work grouping images, skills, and a plan for batch creation

Fields:

  • campaignImageCount Int!: Number of CampaignImages in this batch (tile overview count)
  • createdAt Date
  • id UUID
  • inputImages [BatchInputImage!]!: Product images uploaded for this batch
  • instructions String
  • isGenerated Boolean!: True once every item in the batch (studio + campaign) has finished generating. Derived from task state; unlike status, which flips to completed at dispatch. Single-batch only: do not select on the batch list.
  • mediaGenerationTaskIds [UUID!]!: Ids of the generation tasks this batch has dispatched (product studio + campaign, excluding QA). The workflow runner reads these after executeBatch to declare the render step's wait-set.
  • productStudioCount Int!: Number of ProductStudios in this batch (tile overview count)
  • referenceSheetFileName String: The customer's file name for the looks sheet. Provenance only.
  • referenceSheetLooks [ReferenceLook!]!: Looks read off the uploaded sheet, in reading order. Empty when no sheet was uploaded. The planner reproduces these by matching each description to the batch's products.
  • referenceSheetUrl String: R2 key of the uploaded looks sheet, null when none was uploaded. Upload via POST /api/batches/{batchId}/reference-sheet/upload; re-uploading replaces it.
  • shootType ShootType: Creation-time choice of what this batch produces; a hint for the plan board and planner, not a constraint
  • skills [Skill!]!: Skills referenced by this batch
  • status BatchStatus!
  • teamDomain String!
  • updatedAt Date

BatchInputImage

Uploaded input image for a batch, scanned via Gemini pipeline

Fields:

  • batchId UUID!
  • createdAt Date
  • fileName String!
  • filenameView String: The view this file's name declares, in the team's own vocabulary ("001", "front"). Null when no template matched or the name declares no view. Compare against viewType to flag scan-versus-filename disagreements.
  • id UUID
  • imageUrl String!
  • productDescription String
  • productKey String: Identity shared by every uploaded photo of one product, derived from the team's declared filename convention: the fields their template marks as IDENTITY, joined in pattern order. Group images by this instead of parsing filenames. It is stable across a product's front and back, and across whatever the team marks as OTHER, typically a shoot week or a per-frame camera number, both of which would otherwise split one product into several. It also does not collapse different products that happen to scan as the same category. Null when no template matched.
  • productTitle String
  • updatedAt Date
  • viewType ViewType

BillingCostSummary

Aggregated cost breakdown for the requesting team over a date range; powers the cost-overview chart.

Fields:


BillingFeatureCostBucket

Per-feature cost slice within a BillingCostSummary; one bar in the cost-overview chart.

Fields:

  • feature String!
  • generationCents Int!
  • releaseCents Int!
  • totalCents Int!

BillingLedgerEntry

One entry in the billing ledger.

Fields:

  • aiModel String
  • balanceAfterCents Int!
  • costCents Int!
  • createdAt Date!
  • deltaCents Int!
  • entryDescription String
  • id UUID!
  • kind String!
  • outputCount Int!
  • outputUnit OutputUnit: What outputCount counts on this row: IMAGE, VIDEO or SECOND. Null on top-ups and adjustments. Render this rather than assuming images; product video generation bills per second.
  • pricingVersion String
  • usageType String

BrandAsset

A reusable file a team puts on its ads, a logo first. PNG only.

Fields:

  • archivedAt Date
  • createdAt Date
  • darkGroundImageKey String: The optional PNG for dark grounds. Upload through POST /api/brand-assets/{id}/dark-ground-version/upload.
  • defaultSize Float!: Fraction of the frame's shorter edge taken by the logo's longer side, when an ad sets no size.
  • height Int!
  • id UUID
  • imageKey String!: The PNG for light grounds, and the only version when there is one.
  • minimumSize Float!
  • slug String!: The handle the planning agent uses.
  • title String!
  • width Int!

BrandHeadlineTreatment

How a headline sits on an ad: over the photo, on a solid band beside it, or on a panel over it. A band changes the crop, because the photo fills only what the band leaves.

Fields:

  • bandPosition HeadlineBandPosition
  • bandSize Float: Band height as a fraction of the frame height. Null unless the ground is SOLID_BAND.
  • copySurface HeadlineSurface: Whether the copy sits in the band or on the photo. Null unless the ground is SOLID_BAND.
  • fillColor String: #RRGGBB fill of the band or panel. Decides the ink.
  • ground HeadlineGround!
  • id UUID
  • imageCopyLines ImageCopyLines!: Which lines of copy images with this treatment carry. The scorer, generation and the renderer use only these.
  • presetKey String
  • slug String!: The handle the planning agent uses, such as band-bottom-white.
  • title String!

BrandMemory

Core content model for the Brand Identity feature.

Fields:

  • brandIdentity String!
  • brandName String!
  • copywritingInstructions String: How the brand writes. Followed by media planner copy generation, beneath a plan's own brief.
  • createdAt Date
  • fashionModelInstructions String
  • id UUID
  • photoStyleInstructions String
  • targetGroupInstructions String
  • teamDomain String!
  • updatedAt Date

Campaign

Named container for organizing single shots and group shots

Fields:


CampaignImage

Campaign image for marketing content creation

Fields:


CampaignImageIteration

Campaign image iteration with feedback loop

Fields:


CampaignImageProduct

Product associated with campaign image

Fields:

  • campaignImageId UUID!
  • createdAt Date
  • id UUID
  • isStylingPiece Boolean!: True when this row is a styling piece the look is completed with, rather than part of what the shot is of
  • productDescription String
  • productId String
  • productImage String!
  • productImageId String!
  • productTitle String
  • wardrobeItemId UUID: Which wardrobe article this was stamped from, and what detaches it. Null once that article has been removed from the library.

CampaignImageResource

Analyzed resource content for campaign images

Fields:


CampaignImageResult

AI-generated campaign image result

Fields:

  • aspectRatio AspectRatio
  • campaignImage CampaignImage!
  • campaignImageId UUID!
  • createdAt Date
  • downloadableImageUrl String: The stored file of the latest media release as generated, with no sRGB profile and no AI-provenance statement. To deliver the image, use exportImageUrl.
  • editedImageUrl String: DEPRECATED: use 'images' / 'latestImage'. URL of the most recent photo-editor save (legacy single-slot field).
  • exportImageUrl String: The file to deliver for the latest media release: a JPEG with an sRGB profile and a machine-readable statement that the image is AI-generated (IPTC DigitalSourceType). Content Credentials (C2PA) will be added behind this same URL once they ship, so integrators need no change. Null until the asset is released.
  • favorite Boolean!: Whether the user has marked this result as a favorite
  • id UUID
  • imageKey String!: Cloudflare R2 key for the generated image
  • images [OutputImage!]!: Chronological history of this result's image variants: INITIAL_GENERATION (raw render), then USER_EDITED entries, one per photo-editor save, so earlier edits stay reachable. Same OutputImage shape as Product Studio outputs.
  • isPreview Boolean!: True when this is a low-res preview render (preview mode). Preview results are generation-free and cannot be released or downloaded: releaseCampaignImageResult will reject them. Hide release/download and show a preview badge in the UI; to get a final, re-run generation with preview: false.
  • iterations [CampaignImageIteration!]!
  • latestImage String: Server-side resolution of the most recent stage: the newest entry in the image history. Use this when you just want 'the current image'; use images for the full history.
  • latestMediaRelease MediaRelease: Most recent media release for this result
  • mediaGenerationTask MediaGenerationTask: The media generation task that produced this result
  • mediaReleases [MediaRelease!]!: All media releases for this result
  • model String
  • prompt String!
  • updatedAt Date
  • url String!: DEPRECATED: Use 'imageKey' instead. Returns the Cloudflare R2 key for the generated image.

CampaignSetting

Per-team selection of which AI models to use for Campaign generation. Both enabled = mixed mode (parallel FAL calls, 2 + 2 outputs).

Fields:

  • createdAt Date
  • gptImage25Quality GptImage25Quality!: Which GPT Image 2.5 tier this team renders at while useGptImage25 is on: MEDIUM, HIGH, XHIGH or MAX, in ascending detail and price (about 9c, 18c, 28c and 55c per delivered image). New teams default to HIGH. 1K previews always render at FAL's low tier regardless, so a preview does not preview this setting.
  • id UUID
  • teamDomain String!
  • updatedAt Date
  • useGemini3Pro Boolean!
  • useGptImage25 Boolean!

A logo as one card shows it: its rectangle in output-frame fractions and the version chosen for the ground under it. Derived on read.

Fields:

  • brandAssetId UUID!
  • imageKey String!: The file to draw on this card: the dark-ground version when the ground under the logo is dark and one exists.
  • slot BrandAssetSlot!
  • version BrandAssetVersion!
  • x0 Float!
  • x1 Float!
  • y0 Float!
  • y1 Float!

CopyLengthTarget

A provisional length target for one image line on this card, from its zone and a minimum type size. A target, not a limit: the renderer decides what fits.

Fields:


CopySlotTexts

One slot of copy with its languages. Stored as a row per language, shaped as a map here.

Fields:


CreateBillingPortalSessionResponse

Stripe Customer Portal session for invoice and billing management. Frontend redirects the top window to url.

Fields:

  • url String!

CreateShopifyTopUpChargeResponse

Shopify one-time charge for a top-up. Frontend redirects the merchant to confirmationUrl.

Fields:

  • confirmationUrl String!
  • purchaseId String!

CreateTopUpCheckoutSessionResponse

Stripe Checkout session for a VAT-compliant top-up. Frontend redirects the top window to url.

Fields:

  • sessionId String!
  • url String!

CreateTopUpIntentResponse

[Deprecated] Stripe PaymentIntent for a PAYG top-up. Frontend confirms with clientSecret. Replaced by CreateTopUpCheckoutSessionResponse.

Fields:

  • clientSecret String!
  • paymentIntentId String!

CreditBalanceResponse

Current PAYG credit balance for a team.

Fields:

  • balanceCents Int!
  • currency String!

CurrentTeamResponse

Identity + billing-routing flags for the requesting team.

Fields:

  • adLocales [String!]!: BCP-47 tags this team normally writes ads in. New media plans start from these.
  • id UUID!
  • isPAYG Boolean!
  • teamDomain String!

DesignerChangePlan

The deterministic dependency closure for a change set: which slots regenerate, whether the person base rebuilds, the effective setup, exactly which prompts the composer must author, and human-readable notes on backend-only work.

Fields:


DesignerCollection

Named, tenant-scoped parent that groups Designer Instances and Pattern Revisions. Many-to-many on both joins. Resources stay on DIs; the DesignerCollection is a scope. Use the resourcesInDesignerCollection query to browse all DI-level resources within a collection.

Fields:

  • brief String: Narrative anchor for the collection (customer, mood, references). Agent-authorable. Injected as additional prompt context into every DI generation in the collection.
  • createdAt Date
  • designerInstances [DesignerInstance!]!: Live designs in this collection. Archived designs are left out; unarchiving one returns it here.
  • id UUID
  • patternRevisions [PatternRevision!]!
  • season String
  • status DesignerCollectionStatus!
  • teamDomain String!
  • title String!
  • updatedAt Date

DesignerComposerContext

Context pushed to the composer to author one prompt well: the frozen description + outfit (for a correct keep-clause), the resolved fabric-swatch URL (on a fabric change), the paint-overlay URL (on a paint edit), and the view.

Fields:

  • description String!
  • fabricSwatchUrl String
  • outfitContext String
  • overlayUrl String
  • view DesignerPersonView!

DesignerComposerDetail

One placed detail as the composer needs it to write a render prompt.

Fields:

  • artworkKey String!
  • artworkUrl String
  • label String!: Use verbatim as the name of this artwork's image in the render prompt. generateDesignerRevision refuses a render prompt for this view that does not contain it.
  • markerColor DesignerMarkerColor!: The marker's colour. The render prompt must name it (lowercase word, e.g. purple); generateDesignerRevision checks for it.

DesignerComposerRequest

One shape or render prompt the composer must author. kind=SHAPE carries editFromKey (the base puppet key to edit); kind=RENDER is authored whole (including the keep-clause). The composer must supply a prompt for exactly these slots — generateDesignerRevision 400s on a missing or extra slot.

Fields:


DesignerEffectiveSetup

The base revision's frozen setup overlaid with the change set — the state sync every plan reader sees (authoritative stored state, never conversation memory).

Fields:

  • collectionBrief String
  • collectionId UUID
  • description String
  • fabricMaterialHint String: Source pattern prompt or user intent for composition, not visual verification of the generated swatch.
  • fabricRef UUID
  • fabricStatus ContentGenerationStatus
  • fabricSwatchUrl String
  • fashionModelRevisionId UUID
  • outfitContext String
  • placedDetails [DesignerPlacedDetail!]: The detail set the generation will freeze: the change set's details with marker colours assigned, or the base's set carried forward.
  • sourcePatternRevisionId UUID

DesignerFabric

Designer v4 fabric layer: a frozen, design-owned material swatch created from a connected PatternRevision (and tiled at create time). Renders composite this as the 'fabric' role input; never touched by a shape edit.

Fields:

  • baseFabricId UUID: The fabric this one iterates from, if it was an explicit fabric edit.
  • createdAt Date
  • designerInstanceId UUID!
  • errorMessage String
  • generationModel String
  • id UUID
  • imageKey String
  • imageUrl String: Resolved CDN URL of the frozen swatch. Null while the fabric is still generating.
  • reinterpretation Float!: How far the tiling model was allowed to travel from the source print when this swatch was made, 0 to 1 (default 0.3). Low reproduces the designer's print, high reinterprets it. Stored per swatch, so a slider can show what this one used.
  • sourcePatternRevisionId UUID: The PatternRevision this fabric was materialised from (provenance). The frozen swatch image lives on imageKey, independent of later edits to the shared Pattern.
  • status ContentGenerationStatus!

DesignerInstance

Brandmachine Designer instance: owns inspiration resources, revisions, selected patterns, and the chosen fashion model used across the whole instance

Fields:

  • activeFabric DesignerFabric: The active fabric (the swatch renders use). Null until established.
  • activeFabricId UUID: Designer v4 'fabric' layer pointer: the DesignerFabric whose swatch renders currently composite. Null until a fabric is established.
  • archivedAt Date: When the design was archived. An archived design is hidden from designerInstances and from a collection's designerInstances, still opens by id so old links and revisions work, and refuses every change (generating, uploads, patterns, fabrics, flats, releases) until it is unarchived. Generations already in progress finish and delivered outputs charge normally. Null for a live design.
  • createdAt Date
  • description String: Agent-authored garment description, injected into every generation prompt as a stable anchor. Null until the agent and designer settle on one.
  • designerCollections [DesignerCollection!]!: DesignerCollections this DI belongs to (v3 Cluster B). Many-to-many; a DI can sit in zero, one, or several Collections. Powers the inspector's cross-DI resource browse panel: surface it when this list is non-empty.
  • fabrics [DesignerFabric!]!: All fabrics created for this instance (the active one plus prior iterations).
  • fashionModelRevisionId UUID
  • id UUID
  • latestSizeChartMatchRun SizeChartMatchRun: The newest matcher shortlist for this design, whatever its outcome.
  • outfitContext String: Agent-authored description of the rest of the outfit, around the hero garment. Used for upper-body designs so the model has something concrete to render in the lower-body region. Null for dresses and full-length pieces.
  • resources [DesignerInstanceResource!]!
  • revisions [DesignerInstanceRevision!]!
  • selectedPatternRevisions [PatternRevision!]!: PatternRevisions this instance has selected. Multi-select by design; the agent disambiguates by Pattern.name.
  • sizeChart SizeChart: This design's size chart, copied from a chart in the library. Null until one is created with createDesignerSizeChart.
  • teamDomain String!
  • thumbnailUrl String: Image key of the newest revision's front photo, derived live
  • title String!
  • updatedAt Date

DesignerInstanceResource

Inspiration resource scoped to a DesignerInstance. Image-backed resources have an imageKey and an auto-authored description; text-only resources have a typed text body.

Fields:

  • createdAt Date
  • description String: Gemini Vision description of an image-backed resource, written once at upload. Null for text-only resources. Replaces the v2 analysis field.
  • designerInstanceId UUID!
  • id UUID
  • imageKey String
  • label String!
  • text String

DesignerInstanceRevision

Immutable result row for one generation cycle of a DesignerInstance: the eight image slots (person base, grey puppet, photo renders, technical flats) plus the frozen setup (outfit, description, model ref, fabric pin) this look was built with.

Fields:

  • annotationOverlayKey String: Cloudflare bucket key of the painted composite (v3 Cluster A) when this revision was triggered by paint-and-regenerate. Null otherwise.
  • annotationOverlaySourceSlot OutputSlot: Which slot of the base revision the designer painted on (FRONT or BACK). Travels with annotationOverlayKey; null when no overlay.
  • annotationOverlayUrl String: Resolved public URL of the painted composite, derived from annotationOverlayKey via the Cloudflare CDN. The Genkit composer reads this in ANNOTATION_REGEN mode to attach the painted PNG as multimodal input to Gemini. Null when annotationOverlayKey is null. Treat as transient: the PNG ages out via the R2 lifecycle rule on media/annotation_overlays/.
  • backFlatKey String
  • backFlatUrl String: Resolved public CDN URL of the BACK technical drawing (opt-in flat). Null when backFlatKey is null. Use for multimodal agent reads.
  • backPhotoKey String
  • backPhotoUrl String: Resolved public CDN URL of the BACK photo, derived from backPhotoKey. Null when backPhotoKey is null. Same use as frontPhotoUrl.
  • baseRevisionId UUID
  • createdAt Date
  • designerInstance DesignerInstance: Owning design with its current title, loaded in a team-scoped batch. Renames are reflected on historical revisions too.
  • designerInstanceId UUID!
  • errorMessage String
  • favorite Boolean!
  • frontFlatKey String
  • frontFlatUrl String: Resolved public CDN URL of the FRONT technical drawing (opt-in flat). Null when frontFlatKey is null. Use for multimodal agent reads.
  • frontPhotoKey String
  • frontPhotoUrl String: Resolved public CDN URL of the FRONT photo, derived from frontPhotoKey. Null when frontPhotoKey is null. Use to attach the rendered output as multimodal input to Gemini (diagnose tool, etc.).
  • frozenDescription String: The garment description this revision was generated under. Authoritative per-look description; read this, not the instance's mutable description. Null on a legacy row.
  • frozenFashionModelRevisionId UUID: The fashion model revision this revision's person base used (fixed per design). Null on a legacy row.
  • frozenOutfitContext String: The outfit context this revision's person base reflects. Authoritative per-look outfit; read this, not the instance's mutable outfitContext. Null on a garment with no outfit context or a legacy row.
  • generationProvenance String
  • id UUID
  • intentTag String
  • label String
  • personBackKey String: Designer v4 'person' layer: BACK dressed-base key. Null until generated.
  • personBackUrl String: Resolved CDN URL of the BACK dressed base. Null when personBackKey is null.
  • personFrontKey String: Designer v4 'person' layer: FRONT dressed-base key (the frozen full-body model wearing the outfit context, hero region a neutral placeholder). Carried forward from the base revision on a garment edit, rebuilt on a model/outfit change. Null until generated.
  • personFrontUrl String: Resolved CDN URL of the FRONT dressed base. Null when personFrontKey is null.
  • pinnedFabricId UUID: The frozen DesignerFabric this revision's renders resolve their swatch from (5.5). Immutable per revision; a fabric change sets a new pin, a carry copies the base's. Null for a fabric-less garment or a legacy row.
  • placedDetails [DesignerPlacedDetail!]: The graphics placed on this look, frozen per revision: a details change sets a new set, a carry copies the base's. Read this off the displayed revision to seed the placement editor. Null and an empty list both mean no details.
  • resolvedFabricKey String: The fabric swatch key a render actually composited, stamped at fire time. Null until a render fires or when the garment has no fabric.
  • resolvedFabricUrl String: Resolved CDN URL of the fabric swatch this revision composited, from resolvedFabricKey. Null when resolvedFabricKey is null.
  • shapeBackKey String: Designer v4 'shape' layer: BACK grey-puppet key. Null on legacy revisions and until generated.
  • shapeBackUrl String: Resolved CDN URL of the BACK grey puppet. Null when shapeBackKey is null.
  • shapeFrontKey String: Designer v4 'shape' layer: FRONT grey-puppet key (print-free garment, the editable layer renders composite onto). Null on legacy (v2/v3) revisions and until the puppet is generated.
  • shapeFrontUrl String: Resolved CDN URL of the FRONT grey puppet. Null when shapeFrontKey is null.
  • snapshot DesignerInstanceRevisionSnapshot
  • status ContentGenerationStatus!
  • userRequest String

DesignerInstanceRevisionSlotSnapshot

Per-slot frozen record of prompt + input files for a revision

Fields:


DesignerInstanceRevisionSnapshot

Frozen inputs + per-slot prompts for a DesignerInstanceRevision

Fields:


DesignerPlacedDetail

A graphic placed on a look (patch, logo, placed print), frozen on the revision. Every render of a view it is placed on draws a coloured marker on the grey puppet at the box and passes the artwork as its own image input.

Fields:

  • artworkKey String!
  • artworkUrl String!: Resolved CDN URL of the artwork image, from artworkKey.
  • back DesignerPlacement
  • front DesignerPlacement
  • id UUID!
  • label String!: The name the render prompt gives this detail's artwork image. Unique per revision.
  • markerColor DesignerMarkerColor!: Backend-assigned marker colour, stable for this detail across revisions.
  • sourceResourceId UUID!: The DesignerInstanceResource the artwork was picked from. Provenance for the editor; the resource may since have been deleted, the artwork stays renderable.

DesignerPlacement

A box in fractions (0 to 1) of one view's grey puppet frame: the intended bounds of a placed detail. Sets position and rough size only; rendered patches come out somewhat larger than the box.

Fields:

  • height Float!
  • width Float!
  • x Float!
  • y Float!

DesignerViewDetails

The placed details on one view. Present for every view that has details, whether or not it renders this turn, so a render the composer adds itself (paint on FRONT pulling in BACK) has them too.

Fields:

  • details [DesignerComposerDetail!]!
  • markedPuppetUrl String: The base puppet for this view with the markers drawn on, for reading each marker's garment part and wearer's side. Null when the base has no puppet for this view.
  • view DesignerPersonView!

ExportMediaPlanResult

Fields:

  • alreadyRendering Int!: Renders skipped because an earlier export of the same image is still rendering.
  • failed Int!: Renders that failed before anything was sent: no layout, no headline, or the renderer could not be reached. Each carries its reason in the plan's renders.
  • plan MediaPlan!
  • queued Int!: Renders sent to the renderer.

FashionModel

Fashion model for AI-generated content creation

Fields:


FashionModelCasting

Casting session that generates fashion model candidates

Fields:


FashionModelCastingResult

Single image result from a fashion model casting

Fields:

  • createdAt Date
  • fashionModelCastingId UUID!
  • id UUID
  • imageKey String!
  • model String

FashionModelRevision

Immutable snapshot of an iterative edit on a fashion model

Fields:


FashionModelRevisionResources

Structured resources for a fashion model revision

Fields:

  • beard String
  • bodyShape String
  • description String
  • hairstyle String
  • makeup String

FileNameConvention

How a team's uploaded filenames are read and how delivered filenames are written

Fields:

  • exportPattern String
  • isDefault Boolean!: True when the team has declared nothing and this is the built-in fallback. Present it as 'not set up yet', not as their own configuration.
  • templates [FileNameTemplate!]!
  • viewCodes [FileNameViewCodeMapping!]!

FileNameConventionPreview

Fields:


FileNameConventionProblem

One reason a filename convention cannot be stored

Fields:

  • code FileNameConventionProblemCode!: Stable machine name, for styling or grouping without reading the sentence.
  • message String!: Written for the person building the convention. Display this.
  • templateIndex Int: 1-based, matching the numbering inside message, so the editor can mark the offending row. Null when the problem concerns the whole declaration rather than one template.

FileNameFieldCapture

One field a template captured out of a filename

Fields:

  • name String!
  • value String!

FileNameFieldRule

Fields:


FileNamePreviewRow

Fields:

  • changed Boolean!: True when saving would change this file's product identity. This is the column that matters.
  • currentProductKey String: What this file resolves to under the currently saved convention.
  • exportFileName String
  • fields [FileNameFieldCapture!]!: Every field the template captured, in pattern order. Do not try to derive this by splitting productKey: a field may contain the character that separates the others, so splitting produces wrong boundaries on common names like TEE-01_WHT01_front.
  • fileName String!
  • matchedTemplate Int: 1-based index of the template that matched, matching how templates are numbered in problem messages. Null when nothing matched.
  • productKey String: The identity fields joined in pattern order. Files sharing this group as one product, so it is the column to check when a template marks the wrong fields as identity.
  • viewToken String: The raw token from the field carrying the VIEW role, as the customer wrote it. Null when the template has no view field, which is normal: the delivered name takes its view from the perspective, not from the reference photo.
  • viewType ViewType

FileNameTemplate

Fields:

  • fields [FileNameFieldRule!]!: Only the fields that declare something. A field named in the pattern but absent here is an unconstrained identity field.
  • pattern String!

FileNameViewCodeMapping

Fields:


GroupShot

Multi-model composite image assembled from single shots

Fields:


GroupShotIntermediateRender

Per-person intermediate render for group shot pipeline

Fields:


GroupShotResult

Final composite image from the group shot pipeline

Fields:

  • aspectRatio AspectRatio
  • createdAt Date
  • downloadableImageUrl String
  • editedImageKey String
  • exportImageUrl String: The file to deliver for the latest media release: a JPEG with an sRGB profile and a machine-readable statement that the image is AI-generated (IPTC DigitalSourceType). Content Credentials (C2PA) will be added behind this same URL once they ship, so integrators need no change. Null until the asset is released.
  • favorite Boolean!: Whether the user has marked this result as a favorite
  • groupShotId UUID!
  • hiddenAt Date
  • id UUID
  • imageKey String!
  • latestMediaRelease MediaRelease
  • mediaReleases [MediaRelease!]!
  • model String
  • updatedAt Date

GroupShotSingleShot

Link between a group shot and one of its single shots

Fields:


LocalizedCopy

One line in one language.

Fields:

  • approvedAt Date
  • approvedBy String
  • locale String!
  • origin MediaCopyOrigin!: GENERATED or EDITED. Generation never overwrites an EDITED or approved line unless asked to regenerate.
  • text String!

LuminanceGrid

Relative luminance over one source image, as a coarse grid.

Fields:

  • data String!: Base64, one byte per cell, row-major. Each byte is WCAG relative luminance quantised to 0..255. Covers the WHOLE source at its own aspect ratio.
  • height Int!
  • width Int!

MaterializePlanResult

Result of materializePlan — counts of created draft records

Fields:

  • campaignImagesCreated Int!
  • productStudiosCreated Int!

MediaFormat

One image specification: ratio, exact pixels, byte budget, safe area, and the copy limits that belong to a card.

Fields:

  • aspectRatio String!
  • copyLimitsSourced Boolean!
  • descriptionMaxChars Int
  • headlineMaxChars Int
  • id UUID
  • maxBytes Int
  • overlaysAllowed Boolean!: False where the platform takes a clean image (Google): cards are plain crops, with no headline zone, treatment, logos or text on the image, and export as crops.
  • safeAreaBottom Float
  • safeAreaLeft Float
  • safeAreaRight Float
  • safeAreaTop Float
  • safeZonePublished Boolean!: True when the safe areas are the platform's own published figures, false when they are our conservative default.
  • slug String!
  • targetHeight Int!
  • targetWidth Int!
  • title String!

MediaGenerationTask

Tracks media generation tasks for notification center

Fields:

  • campaignImage CampaignImage: Parent CampaignImage (non-null only for CampaignImage tasks)
  • campaignImageId UUID: FK to the parent CampaignImage
  • campaignImageResults [CampaignImageResult!]!: CampaignImage results produced by this task
  • completedAt Date
  • createdAt Date
  • designerInstanceRevision DesignerInstanceRevision: Parent DesignerInstanceRevision (non-null only for DesignerRevisionSlot tasks; one task per slot, up to four tasks point at the same revision)
  • designerInstanceRevisionId UUID: FK to the parent DesignerInstanceRevision
  • errorMessage String
  • fashionModelCasting FashionModelCasting: Parent FashionModelCasting (non-null only for FashionModelCasting tasks)
  • fashionModelCastingId UUID: FK to the parent FashionModelCasting
  • fashionModelRevision FashionModelRevision: Parent FashionModelRevision (non-null only for FashionModelRevision tasks)
  • fashionModelRevisionId UUID: FK to the parent FashionModelRevision
  • groupShot GroupShot: Parent GroupShot (non-null only for GroupShot tasks)
  • groupShotId UUID: FK to the parent GroupShot
  • id UUID
  • mediaPlanId UUID: The media plan this task works on: an export, a copy run, or segmenting one of its sources.
  • patternRevision PatternRevision: Parent PatternRevision (non-null only for PatternRevision tasks)
  • patternRevisionId UUID: FK to the parent PatternRevision
  • phase String: Optional sub-state for multi-stage flows (e.g. REMOVING_BACKGROUND, CORRECTING_COLOR). Status stays IN_PROGRESS while phase transitions; phase is for UX granularity only.
  • productStudio ProductStudio: Parent ProductStudio (non-null only for ProductStudio tasks)
  • productStudioId UUID: FK to the parent ProductStudio (non-null only for ProductStudio tasks)
  • productStudioOutputs [ProductStudioOutput!]!: ProductStudio outputs produced by this task
  • productStudioPerspective ProductStudioPerspective: ProductStudio perspective being generated (non-null only for ProductStudio tasks)
  • productStudioPerspectiveId UUID: FK to the ProductStudio perspective being generated
  • productVideo ProductVideo: Parent ProductVideo (non-null only for ProductVideo tasks)
  • productVideoId UUID: FK to the parent ProductVideo
  • shootingLocation ShootingLocation: Parent ShootingLocation (non-null only for ShootingLocation tasks)
  • shootingLocationId UUID: FK to the parent ShootingLocation
  • sizeChartAnnotationId UUID: FK to the parent SizeChartAnnotation
  • sizeChartDesignerInstanceId UUID: The design whose size chart an annotation task draws, for navigating from the tasks panel. Non-null only for size chart annotation tasks.
  • slot OutputSlot: Designer output slot derived from its standardized task title. Null for other task types or unrecognized titles.
  • status ContentGenerationStatus!
  • teamDomain String!
  • title String!
  • type TaskType!
  • updatedAt Date

MediaPlacement

An ad unit in the delivery catalog: the surface, how many cards it holds, and the copy limits that belong to the advertisement rather than to a card.

Fields:

  • channel MediaChannel!
  • copyLimitsSourced Boolean!: False when a limit above is null because nobody has sourced it yet, rather than because the slot does not exist here. Copy generation must refuse a row with this false.
  • ctaMaxChars Int
  • descriptionMaxChars Int
  • headlineMaxChars Int
  • id UUID
  • maxCards Int!
  • minCards Int!
  • placementCode String!
  • primaryTextMaxChars Int
  • slug String!
  • title String!

MediaPlan

The unit a human reviews and approves. No stored status: whether it is approved is derived from its placements rather than written down in a third place that can disagree.

Fields:

  • brandAssets [MediaPlanBrandAsset!]!: The plan's default logo set, in order.
  • copyGeneratingSince Date: Set while copy is being generated; poll until it clears.
  • copyGenerationError String
  • createdAt Date
  • headlineTreatment BrandHeadlineTreatment
  • headlineTreatmentId UUID: The plan's default treatment. Null means plain type over the photo.
  • id UUID
  • instructions String
  • locales [String!]!: BCP-47 tags this plan's copy is written in, the first being the main one.
  • name String
  • placements [PlannedPlacement!]!
  • renders [MediaPlanRender!]!: One render per exported card per language, the latest export of each. Poll while any is QUEUED. Includes languages the plan no longer lists; filter by the plan's locales.
  • sources [MediaPlanSource!]!
  • teamDomain String!
  • updatedAt Date

MediaPlanBrandAsset

One logo in a plan's default set.

Fields:

  • brandAsset BrandAsset!
  • brandAssetId UUID!
  • position Int!
  • size Float: Null uses the asset's default size.

MediaPlanRender

One card's image in one language, rendered with its copy and logos.

Fields:


MediaPlanRenderFailure

Fields:

  • characters [String!]!: The characters the font cannot draw, for GLYPHS_MISSING.
  • code MediaPlanRenderFailureCode!
  • message String!
  • slot MediaCopySlot: The line the failure is about, for TEXT_DID_NOT_FIT and GLYPHS_MISSING.

MediaPlanRenderFile

Fields:

  • bytes Int
  • height Int
  • key String!
  • reused Boolean!: True when an identical render already existed and nothing was drawn again.
  • url String!: The finished JPEG on the CDN. Download through /download/<key>, which adds nothing to renders: they already carry the sRGB profile and the AI statement.
  • width Int

MediaPlanRenderFit

Fields:

  • atFloor Boolean!: True when the headline only fitted at the smallest size allowed.
  • headlineSizePx Float!
  • hyphenated Boolean!
  • lines Int!

MediaPlanSource

One finished output the human selected, owned as a copy so editing or deleting the original cannot change what was planned.

Fields:

  • campaignImageId UUID: The campaign shot this source was rendered for, so a picker can offer that shot's other renders. Null for other source types, or when the render has since been deleted.
  • faceBox NormalisedBox: Where the face is in the source. The layout scorer refuses any headline band that touches it.
  • hasFaceBox Boolean!: False either because segmentation is still in flight or because there is no face in the picture. The two are told apart by the source's tasks, not here.
  • hasPersonBox Boolean!
  • id UUID
  • isMeasured Boolean!: Whether the tone measurement landed.
  • luminanceGrid LuminanceGrid
  • personBox NormalisedBox
  • position Int!
  • sourceAspectRatio String
  • sourceHeight Int
  • sourceId UUID!
  • sourceKey String!: The handle the planning agent sees, such as look-1. The agent never handles a UUID.
  • sourceMediaKey String!
  • sourceResolution String
  • sourceType String!
  • sourceWidth Int

MediaRelease

A media release of a generated asset (ProductStudioOutput, CampaignImageResult, etc.)

Fields:

  • campaignImageResult CampaignImageResult: The campaign image result this release belongs to, if any. Loaded with the release in releasedImages.
  • createdAt Date: When the asset was first released.
  • exportImageUrl String: The file to deliver: a JPEG with an sRGB profile and a machine-readable statement that the image is AI-generated (IPTC DigitalSourceType). Content Credentials (C2PA) will be added behind this same URL once they ship. Null for video releases.
  • groupShotResult GroupShotResult: The group shot result this release belongs to, if any. Loaded with the release in releasedImages.
  • id UUID
  • objectKey String!
  • productStudioOutput ProductStudioOutput: The product studio output this release belongs to, if any. Loaded with the release in releasedImages.
  • teamDomain String!
  • updatedAt Date: When the release last changed: first release, re-release, or an edit saved after release.
  • upscaleFactor Float

NormalisedBox

A rectangle as fractions of the frame it sits in, centre-first.

Fields:

  • cx Float!
  • cy Float!
  • h Float!
  • w Float!

OnboardingSampleDataResult

Response for onboarding sample data creation

Fields:

  • created Boolean!

OutputImage

One entry in an output's chronological image history (Product Studio outputs and campaign image results).

Fields:

  • createdAt Date!
  • floorStatus String: BREUNINGER_FRAMED entries only: floor-reserve outcome. Always 'cropped' on entries written from 2026-08-28, when a render with too little room started failing instead of coming back uncropped. Older entries may still read 'best_effort', meaning the source was returned unframed.
  • key String!: R2 key (or full URL for seed assets) of this variant.
  • shadowFlag String: BREUNINGER_FRAMED entries only: shadow verdict from the framing service (soft | stark | wrong_dir). Informational flag, never a gate.
  • stepErrors [SpecStepError!]!: SPEC_APPLIED entries only: which steps of the Spec failed and why, empty when everything worked. A failure here is advisory and never blocks release: the render is paid for, so what survived is delivered and what did not is recorded. When every step failed, key points at the output's existing image and no new file was written. Show it as a warning on the image; do not gate export on it.
  • type OutputImageType!
  • upscale Float: BREUNINGER_FRAMED entries only: how much the crop was scaled to reach the delivered size. Above 1.0 means the render lacked pixels and the difference was interpolated, which reads as softness. Below 1.0 means it had pixels to spare. Null on entries written before 2026-08-31.
  • url String!: Full CDN URL for this variant.

Pattern

Shop-level, agent-iterable pattern asset used by Designer Instances. Produces a single image per revision.

Fields:


PatternInputReference

Persistent inspiration reference attached to a Pattern. Label + image. Uploaded via POST /api/patterns/references.

Fields:

  • createdAt Date
  • id UUID
  • imageKey String!
  • label String!
  • patternId UUID!

PatternRevision

Immutable output of one iteration on a Pattern.

Fields:


PatternRevisionInput

One labelled reference snapshotted onto a PatternRevision at generation time.

Fields:

  • imageKey String!
  • label String!

Plan

Fields:

  • createdAt Date
  • handle String!
  • id UUID
  • name String!
  • productShortQuota Int!
  • updatedAt Date

PlannedAsset

One card: one source in one format, cropped, with a headline zone. All geometry is normalised fractions, never pixels, because a source's true size is sometimes unknown.

Fields:

  • copy [CopySlotTexts!]!: This card's copy (text on its image, and Meta's per-card fields), per slot, per language. Includes languages the plan no longer lists; filter by the plan's locales.
  • copyLengthTargets [CopyLengthTarget!]!
  • cropH Float
  • cropW Float
  • cropX Float
  • cropY Float
  • faceFullyInside Boolean!: False when no crop could hold the whole face and it centre-cropped instead. Separate from layoutState because a card can be centre-cropped and still have a good zone.
  • fillColor String: #RRGGBB of the band or panel this card was laid out with. Null when it has neither.
  • format MediaFormat
  • headlineGround HeadlineGround!: What this card's headline sits on. SOLID_BAND zones are placed by the band and cannot be dragged; PANEL takes its ink from the panel colour.
  • id UUID
  • ink String
  • layoutEditedAt Date: Non-null when a human moved this card by hand. Re-scoring skips such a card, so an automatic recompute cannot silently undo the adjustment.
  • layoutState MediaLayoutState!
  • logos [CardLogo!]!: The ad's logos as this card shows them. Empty until the card is laid out.
  • measuredContrast Float: Advisory, never a gate. Real contrast depends on the type treatment, which is downstream of a brand type spec.
  • mediaFormatId UUID!
  • mediaPlanSourceId UUID!
  • method MediaAdaptationMethod!
  • notes String
  • photoX0 Float: The part of the output frame the cropped photo fills, as fractions of the frame. The whole frame unless a band takes a share. The crop fills this area, not the frame, so a zone maps to the source through this and then the crop.
  • photoX1 Float
  • photoY0 Float
  • photoY1 Float
  • position Int!
  • suggestions [MediaLayoutSuggestion!]!: Optional improvements for this card. Nothing here is a fault: a card with suggestions is ready to approve and export.
  • warnings [MediaLayoutWarning!]!: What is wrong with this card as it stands: the headline or a logo covers the face, sits where the platform's interface goes, overlaps, or does not fit. Derived on read so every client sees it, including the planning agent. Improvements that are optional are in suggestions, never here.
  • zoneName String
  • zoneX0 Float
  • zoneX1 Float
  • zoneY0 Float
  • zoneY1 Float

PlannedPlacement

One advertisement. Approved as a unit, because approving three of five carousel cards is not a state that means anything.

Fields:

  • approvedAt Date
  • approvedBy String
  • brandAssets [PlannedPlacementBrandAsset!]!: The logos on this ad, in order, with the slot each sits in.
  • brandAssetsOverridden Boolean!: False while this ad carries the plan's logo set, true once it has its own.
  • cards [PlannedAsset!]!
  • copy [CopySlotTexts!]!: Copy that belongs to the whole ad (Meta's ad-level fields), per slot, per language.
  • headlineTreatment BrandHeadlineTreatment
  • headlineTreatmentId UUID: This ad's own treatment. Null inherits the plan's.
  • id UUID
  • mediaPlacementId UUID!
  • notes String
  • placement MediaPlacement
  • position Int!
  • readyToApprove Boolean!: Whether this ad can be approved: enough cards, every card laid out with the whole face in frame, and no warnings. Suggestions never block. The same rule SET_APPROVAL applies for the planning agent.

PlannedPlacementBrandAsset

One logo on one ad, with its position. Shared by every card of the ad.

Fields:

  • brandAsset BrandAsset!
  • brandAssetId UUID!
  • position Int!
  • size Float: Null uses the asset's default size.
  • slot BrandAssetSlot: Where the logo sits on every card of this ad. Null when no slot fits every card.
  • slotEditedAt Date: Non-null when a person placed the logo. The scorer leaves it where it is.

PricelistEntry

One row of the public PAYG pricelist. Every row is something a merchant can actually be charged; rates that exist only as internal fallbacks are not returned.

Fields:

  • chargeCents Int!
  • currency String!
  • label String!: Merchant-facing name for this charge, e.g. "GPT Image 2.5 (high)". Render this; do not derive a name from usageType.
  • outputUnit OutputUnit!: What chargeCents buys one of: IMAGE, VIDEO or SECOND. Product video generation is priced per second of video.
  • pricingVersion String!
  • tier PricingTier!: Which half of the pricing model this charge belongs to: GENERATION per attempt while creating, RELEASE once when a finished asset is exported.
  • usageType String!

ProductStudio

Core content model for the ProductStudio feature.

Fields:

  • batch Batch: Parent batch if this is a draft studio (non-null means part of a plan)
  • createdAt Date
  • exportFileNames [ProductStudioExportName!]!: What each active perspective would deliver this studio as, before anything is rendered. One row per perspective, each carrying a name or the reason it has none.
  • fashionModelRevision FashionModelRevision: The selected fashion model revision for this studio session
  • id UUID
  • inputs [ProductStudioInput!]!: Product inputs for this studio session, sorted by creation date (newest first)
  • isGenerated Boolean!: True once all of this studio's render tasks have settled (derived from MediaGenerationTask, not the stored status which never rolls up). False while generating or before generation starts.
  • outputs [ProductStudioOutput!]!: Generated outputs from this studio session
    • includeArchived Boolean
    • productStudioPerspectiveId UUID
    • favoritesOnly Boolean
  • status ContentGenerationStatus!
  • stylingResources [ProductStudioStylingResource!]!: Styling instructions per perspective for this studio session
  • teamDomain String!: The Shopify team domain this studio belongs to
  • title String
  • updatedAt Date

ProductStudioExportName

What one perspective would deliver this studio as, before anything is rendered

Fields:

  • conflictingFileNames [String!]!: The specific uploaded files that disagree, when the reason is a disagreement. Empty otherwise.
  • exportCode String: This perspective's token for delivered filenames, or null if it has none.
  • fileName String: What this studio would be delivered as for this perspective, with no extension. Null when it cannot be computed, in which case unavailableReason says why.
  • perspectiveId UUID!
  • perspectiveName String!
  • unavailableReason ProductStudioExportNameUnavailableReason: Why there is no name. Present exactly when fileName is null.

ProductStudioHomeCard

A single card on the Home view, carrying everything the UI renders for one studio.

Fields:

  • perspectivesGenerated Int!: Distinct perspectives this studio has at least one output for.
  • perspectivesPicked Int!: Subset of perspectivesGenerated where at least one output is favorited.
  • reviewState StudioReviewState!
  • studio ProductStudio!
  • thumbnailUrl String: Full Cloudflare URL. TODO: oldest input image. IN_PROGRESS/DONE: most recently favorited output. Null if no inputs and no outputs exist.

ProductStudioHomeDigest

Aggregated Home view payload: 'needs your attention' plus 'recently generated'.

Fields:

  • needsAttention [ProductStudioHomeCard!]!: TODO and IN_PROGRESS studios, most-recently-active first, capped at 10.
  • recentlyGenerated [ProductStudioHomeCard!]!: DONE studios whose last activity is within the past 7 days, most-recent first, capped at 10.

ProductStudioInpaintResult

Pivot model representing the many-to-many relationship between inputs and outputs with sequential inpainting.

Fields:

  • createdAt Date
  • id UUID
  • inpaintedResult String: Final inpainted image URL for this combination
  • inputId UUID!: The ProductStudioInput this result belongs to
  • isComplete Boolean!: Whether this inpaint result is complete
  • isReadyForInpainting Boolean!: Whether this record is ready for inpainting
  • outputId UUID!: The ProductStudioOutput this result belongs to
  • sceneMask String: Scene mask URL for this input in this specific scene

ProductStudioInput

Individual product input within a ProductStudio session.

Fields:

  • createdAt Date
  • fileName String: Name of the file the customer uploaded, kept verbatim and parsed on read against the team's filename convention. Null for inputs created before the column existed. Use it to show which files an ambiguous studio is disagreeing about.
  • filenameView String: The raw view token the filename declares, before translation through the team's view codes. Null when nothing matched.
  • id UUID
  • inpaintResults [ProductStudioInpaintResult!]!: Inpaint results for this input across all outputs
  • isHero Boolean!: Marks this input as a focus / hero product. Perspectives with useHeroOnly=true filter generation down to hero inputs only.
  • isStylingPiece Boolean!: True when this input is a styling piece the look is completed with, rather than part of what the shot is of. Never a product: styling pieces stay out of exports and product grouping.
  • productDescription String: Detailed product description
  • productDetailPrompt String: Guidance prompt to guide AI image generation
  • productId String: Optional Shopify product ID if attached to a product
  • productImage String!: The uploaded image URL (stored in Shopify after upload)
  • productImageId String!: The Shopify file ID (GID) for the uploaded image
  • productKey String: Identity shared by every photo of one product, derived from the team's declared filename convention. Group inputs by this rather than by productTitle, which is a scan artifact and disagrees across views of one product more often than not. Null when no template matched, and null for a styling piece, which carries no filename.
  • productStudioId UUID!: The ProductStudio this input belongs to
  • productTitle String: User-provided title/description for this input
  • viewType ViewType!: View type of this product input (front, back, other, or cropped)
  • wardrobeItemId UUID: Which wardrobe article this was stamped from, and what detaches it. Null once that article has been removed from the library; the input itself is unaffected.

ProductStudioOutput

Generated image from a ProductStudio session. Each output passes through an additive pipeline of up to three stages: (1) raw AI generation → imageKey; (2) optional background color correction, only when the perspective carries a backgroundHexColor → correctedImageUrl; (3) optional user edit from the photo editor → editedImageUrl. Each stage persists independently, so older stages remain queryable for before/after views and reverts. latestImage returns the newest entry in the image history (chronological).

Fields:

  • completionPercentage Float!: Returns progress based on which images are available
  • correctedImageUrl String: URL for the auto-corrected variant (stage 2 of the pipeline): the raw AI output run through the background-color-correction pipeline so the backdrop matches the perspective's backgroundHexColor exactly. Set only when the perspective carries a backgroundHexColor and correction has completed. Built on top of imageKey and remains populated even after a subsequent user edit, so the frontend can show pre-edit state or revert.
  • createdAt Date
  • downloadableImageUrl String: The stored file of the latest media release as generated, with no sRGB profile and no AI-provenance statement. To deliver the image, use exportImageUrl.
  • editedImageUrl String: URL for the user-edited variant (stage 3 of the pipeline). Produced when the user opens the photo editor and saves on top of whichever earlier stage was current at the time (corrected if present, otherwise raw). Set only after the user actually edits.
  • evaluation ProductStudioOutputEvaluation: Automated quality evaluation of the raw AI generation (imageKey): a 0..1 score and a one-line comment, produced by Gemini shortly after generation. Null until scoring completes, or if scoring failed. Always reflects the raw generation, never the corrected or user-edited variant.
  • exportFileName String: The filename this image should be delivered as, assembled from the team's declared convention: the product identity in its input filenames plus the export code of the perspective that rendered it. No extension — pick that at download. Null when the team declared no export pattern, or when the studio resolves to more than one product identity and there is therefore no single correct name; fall back to the existing name and tell the user why.
  • exportImageUrl String: The file to deliver for the latest media release: a JPEG with an sRGB profile and a machine-readable statement that the image is AI-generated (IPTC DigitalSourceType). Content Credentials (C2PA) will be added behind this same URL once they ship, so integrators need no change. Null until the asset is released. The download is named after the stored file; name it from exportFileName to follow the team's naming convention.
  • favorite Boolean!: Whether the user has marked this output as a favorite
  • finalImageUrl String: DEPRECATED: Use 'imageKey' instead. Returns the Cloudflare R2 key for the final composed image.
  • id UUID
  • imageKey String: Cloudflare R2 key for the raw AI output (stage 1 of the pipeline). Set once generation completes and remains populated even after later stages run, so the frontend can show the pre-correction / pre-edit state or revert.
  • images [OutputImage!]!: Chronological history of this output's image variants: INITIAL_GENERATION (raw render), HEX_BACKGROUND_CORRECTED (bg-correct service), USER_EDITED (one entry per photo-editor save, so earlier edits stay reachable), BREUNINGER_FRAMED (Breuninger crop). The last entry by createdAt is what latestImage returns. Prefer this over the legacy per-variant fields for stage displays.
  • inpaintResults [ProductStudioInpaintResult!]!: Inpaint results for this output across all inputs
  • isPreview Boolean!: True when this is a low-res preview render (preview mode). Preview outputs are generation-free and cannot be released or downloaded: releaseProductStudioOutput will reject them. Hide release/download and show a preview badge in the UI; to get a final, re-run generation with preview: false.
  • latestImage String: Server-side resolution of the most recent stage: the newest entry in the image history (chronological; in the normal pipeline that matches the old edited > corrected > raw priority). Use this when you just want 'the current image'; use images when you need the full history or before/after views.
  • latestMediaRelease MediaRelease: Most recent media release for this output
  • mediaGenerationTask MediaGenerationTask: The media generation task that produced this output. Its status and errorMessage are how a failure that happened BEFORE any image was written becomes visible: a Spec that could not be submitted fails the task and leaves the output carrying only its raw render. A failure DURING the Spec is the other case and lands on the image entry's stepErrors instead.
  • mediaReleases [MediaRelease!]!: All media releases for this output
  • model String: Which AI model rendered this output, as the raw AiModel value (GEMINI_3_PRO, NANO_BANANA_2, GPT_IMAGE_2_5_HIGH, ...). This is what produced THIS image, not what the perspective is set to now. Null for outputs generated before model attribution shipped; show nothing rather than a placeholder.
  • productStudio ProductStudio!: Parent ProductStudio session
  • productStudioId UUID!: The ProductStudio this output belongs to
  • productStudioPerspectiveId UUID!: The perspective this output was generated for. Read this directly when you only need the perspective ID; avoid walking through mediaGenerationTask.productStudioPerspective.id which fires per-output N+1 queries.
  • updatedAt Date

ProductStudioOutputEvaluation

Automated quality evaluation of a ProductStudioOutput's raw AI generation, scored against the product input(s) by Gemini.

Fields:

  • comment String!: One-line human-readable explanation of the score.
  • createdAt Date
  • id UUID
  • model String!: The model id that produced the score, e.g. gemini-3.7-flash.
  • score Float!: Quality score from 0.0 (severe problems: wrong product, colour shift, distortion, artefacts) to 1.0 (excellent: faithful to the product, clean, professional).

ProductStudioPerspective

Perspective configuration for Product Studio Outputs.

Fields:

  • acceptedViewTypes [ViewType!]!: Which view types this perspective accepts (e.g., [front], [front, back], or all)
  • aiModel AiModel!: Which AI model renders this perspective: NANO_BANANA_2 (fast pack shots), GEMINI_3_PRO (balanced), GPT_IMAGE_2_5_MEDIUM, GPT_IMAGE_2_5_HIGH, GPT_IMAGE_2_5_XHIGH or GPT_IMAGE_2_5_MAX (best for logos and prints; the four tiers run about 9c, 18c, 28c and 55c per delivered image). GPT Image 2 was replaced by GPT Image 2.5 on 2026-09-10; none of its values are accepted any more.
  • archivedAt Date: When set, the perspective is archived and hidden from the default list.
  • aspectRatio AspectRatio
  • backgroundHexColor String: 6-character hex color for the studio backdrop (e.g. 'ff0077'), without # prefix. Null means no specific backdrop color.
  • createdAt Date
  • exportCode String: Token representing this perspective in delivered filenames ("001", "FRONT"). Free-form and never interpreted. Separate from name on purpose: download filenames used to be derived from the display name, so renaming a perspective silently renamed every past delivery.
  • groupId UUID: The rail tab this perspective is filed under, or null for ungrouped. The id only: there is deliberately no group relation field here, because it would cost a query per perspective on a list the rail always fetches whole. Read the groups once via getAllProductStudioPerspectiveGroups and join client-side.
  • guideKey String: OPTIONAL shadow guide for plateKey: the same photograph with an outline marking where the shadow may fall. UPLOADED, never generated (changed 4 Sep 2026; 66 renders found a drawn bound changed neither the shadow's direction nor its extent). A guide requires a plate, a plate does NOT require a guide, and this is null on most plates. It is positioned against its own plate's silhouette, so one made for a different plate marks the wrong floor.
  • id UUID
  • isDefault Boolean!
  • isLocked Boolean!: Locked marketplace-preset template: updateProductStudioPerspective accepts only aiModel changes (all other fields must be sent unchanged) and delete is rejected; archiving is allowed. Render the fields read-only except the model picker. Grouping and ordering are NOT locked: a locked slot can still be filed under a group and dragged around the rail.
  • isProductOnly Boolean!: When true, generates product-only pack shots without a fashion model.
  • name String!
  • outputs [ProductStudioOutput!]!
  • plateKey String: The team's own studio plate: a photograph of the empty set with the person replaced by a grey silhouette. It pins where the model stands, how large they are in the frame, and which room it is. A plate may stand alone; see guideKey.
  • presetKey PerspectivePresetKey: Which marketplace slot this perspective points at (e.g. BREUNINGER_FRONT), or null for regular perspectives. The slot's configuration lives in code and is never copied into this row.
  • prompt String!
  • qaPrompt String: Whether this perspective is quality-checked, and what extra it is checked for. Three states: null means it is NOT SCORED AT ALL (no evaluation, no quality-check task); an empty string means it is scored on the standard rubric with nothing added; text means it is scored on the standard rubric plus that text. Empty and null are different settings, not two spellings of "nothing". The text describes what "correct" looks like for this view ("the sole must be fully visible") and never reaches the renderer, that is what prompt does.
  • shootingLocationRevision ShootingLocationRevision: Optional generated scene the subject is composited into. When set it replaces the flat backgroundHexColor backdrop and background correction is skipped.
  • shootingLocationRevisionId UUID: The attached scene (shooting location revision) this perspective renders into, if any. Read this directly when you only need the id.
  • sortOrder Int: 0-based position in the team's rail, or null if this perspective has never been placed. Unplaced perspectives sort after every placed one, in creation order. Team-wide: one person's reorder moves the rail for everybody.
  • specCrop String: How this perspective's outputs are cropped, as the JSON crop object, or null if they are not cropped. Placement is anchored (pin a top feature and the soles), fitted (inscribe the subject with a margin) or frame (inscribe the frame, no subject). On a marketplace slot this reflects the row, which is unused: the slot's own crop comes from code.
  • targetRatioH Int: Free-form target aspect ratio height (e.g. 9 in 7:9). Set with targetRatioW.
  • targetRatioW Int: Free-form target aspect ratio width (e.g. 7 in 7:9). Set with targetRatioH. When present, renders generate at the closest native ratio and are cropped down to this exact ratio. Null means no crop.
  • teamDomain String!
  • updatedAt Date
  • useHeroOnly Boolean!: When true, generation uses only inputs marked as hero. Use for perspectives like fabric samples where accessories would dilute the output.

ProductStudioPerspectiveGroup

A tab on the perspective rail: the team's own filing of its perspectives. Team-wide. Deleting one returns its members to the ungrouped rail and never deletes a perspective.

Fields:

  • createdAt Date
  • id UUID
  • name String!
  • purpose String: What this group is for, in the team's own words ("the perspectives we ship to our own webshop"). Read by the agent to resolve a phrase like "add my ecommerce options" to a group. A matching hint only: it never reaches a render prompt, so editing it cannot change how anything is generated.
  • sortOrder Int: 0-based position of this tab in the rail, or null if it has never been dragged. Unplaced tabs sort after every placed one, in creation order.
  • teamDomain String!
  • updatedAt Date

ProductStudioSetting

Settings for Product Studio feature customization.

Fields:

  • createdAt Date
  • id UUID
  • instructions String
  • scanInstructions String
  • teamDomain String!
  • updatedAt Date

ProductStudioStylingResource

Styling instructions for a specific ProductStudio session and perspective

Fields:

  • createdAt Date
  • id UUID
  • productStudioId UUID!
  • productStudioPerspectiveId UUID!
  • stylingInstructions String!

ProductVideo

Core content model for the Product Shorts feature.

Fields:

  • buttons [VideoButton!]: Array of interactive buttons with labels and descriptions
  • createdAt Date
  • durationSeconds Int!: Length in seconds of the video this row last generated, and the length a regenerate repeats. Generation is billed per second.
  • id UUID
  • modelType VideoModelType: The AI model used for video generation
  • productId String
  • productImage String
  • productImageId String
  • productTitle String
  • progress Progress!: Current progress information for the video generation flow
  • prompt String: Custom prompt for video generation
  • status ContentGenerationStatus!
  • teamDomain String!: The Shopify team domain this video belongs to
  • updatedAt Date
  • videoUrl String: The result of the genai video generation process.

Progress

Progress information for long-running flows

Fields:

  • message String!
  • percentage Float!

ReferenceLook

One look as read off an uploaded looks sheet.

Fields:

  • description String!: Every garment in the look, top to bottom, with type, colour, fit and any readable print; says so when a slot is absent.
  • id String!: look-1...look-N in sheet reading order, assigned by the backend. Regenerated on re-upload, so not stable across one.

ReleasedImagesPage

One page of the releasedImages feed.

Fields:

  • cursor String: Pass as after on the next call. Store it after each sync; it is null only when the team has never released an image.
  • hasMore Boolean!: True when more releases follow this page right now. Keep paging until it is false.
  • releases [MediaRelease!]!

RenderSize

A render's size in pixels, as the model delivers it, before any crop.

Fields:

  • height Int!
  • width Int!

SetFileNameConventionResult

Fields:


ShootingLocation

ShootingLocation for marketing content creation

Fields:


ShootingLocationRevision

Immutable snapshot of a shooting location generation cycle

Fields:


ShootingLocationRevisionResources

Structured resources for a shooting location revision

Fields:

  • extras String
  • lighting String
  • location String
  • mood String

ShopifyPageInfo

Pagination info for Shopify queries

Fields:

  • endCursor String
  • hasNextPage Boolean!

ShopifyProduct

A Shopify product from the Admin API

Fields:


ShopifyProductImage

A Shopify product image

Fields:

  • altText String
  • height Int
  • id String!
  • url String!
  • width Int

ShopifyProductsResult

Paginated result of Shopify product search

Fields:


ShopifyProductVariant

A Shopify product variant

Fields:

  • id String!
  • inventoryQuantity Int
  • price String!
  • sku String
  • title String!

SizeChart

A size chart: points of measure down, sizes across, every value computed as base + adjustment + grade step. Uploaded standard specs and design charts share this type.

Fields:

  • annotation SizeChartAnnotation: The technical drawings with this chart drawn on. Design charts only.
  • baseSize String!: The size adjustments are made at. Every other size is base plus its grade step.
  • code String: The customer's identifier for an uploaded spec. Null on design charts.
  • createdAt Date
  • department String!: The customer's target group, e.g. boys or women. Matching stays inside one department.
  • derivedFromChartId UUID: The chart this one copied its rows from. May no longer exist.
  • designerInstanceId UUID
  • garmentType String!: The customer's own word for the garment type. Not a fixed list: departments and customers use their own vocabulary.
  • id UUID
  • isComplete Boolean!: False when any row records grade steps and no absolute value. Such rows print no values and refuse adjustments; show a warning.
  • name String!
  • patternGroup String: Shared by charts that are readouts of one pattern, e.g. one tee finished with a 2.2 cm and a 2.8 cm neck trim. Siblings are identical on every shared row: present them together, never as a preference of one over the other. Null when the chart has no siblings.
  • productGroup String
  • rows [SizeChartRow!]!: Points of measure in display order, with their values at every size.
  • sizes [String!]!: Size labels in grading order. Every row's gradeDeltaHundredths and valuesHundredths line up with this.
  • source SizeChartSource!: UPLOADED: a customer's standard spec, never adjusted. DERIVED: a design's chart, copied from another chart.
  • sourceFile String
  • supersededAt Date: Set when a later upload replaced this uploaded chart. Superseded charts stay so design charts can still name them.
  • updatedAt Date

SizeChartAdjustment

A change at the base size on a design chart, in hundredths of a cm.

Fields:


SizeChartAnnotation

A design revision's technical drawings with the size chart's base-size values drawn on.

Fields:

  • backUrl String
  • createdAt Date
  • designerInstanceRevisionId UUID!: The revision whose technical drawings were annotated.
  • errorMessage String
  • frontUrl String
  • id UUID
  • isOutOfDate Boolean!: True when the chart changed after this drawing was made (an adjustment). Offer to annotate again.
  • lines [String!]!: The label lines drawn.
  • status ContentGenerationStatus!: COMPLETED once both views landed.

SizeChartMatchCandidate

Fields:

  • code String
  • confidence Int!: 1 (unlikely) to 5 (strong). Ranks candidates; never sets a measurement.
  • name String!
  • outsideGarmentType Boolean!: True when this chart is a different garment type than the design was placed in. When every candidate has it, say that no chart of the design's type exists.
  • patternGroup String: Candidates sharing a pattern group share a rank and are siblings of one pattern (e.g. two trim widths). Present them together as one choice, never as a ranking.
  • rank Int!
  • rationale String!
  • sizeChartId UUID!

SizeChartMatchRun

One matcher shortlist for a design and what the designer did with it. No accuracy claim is made for the matcher.

Fields:

  • candidates [SizeChartMatchCandidate!]!: Two or three charts, best first. Show the differences between them; never present one as the answer. Also offer every chart in the library and a 'none of these fit' escape.
  • createdAt Date
  • department String!
  • designerInstanceId UUID
  • designerInstanceRevisionId UUID!
  • garmentTypeConfident Boolean!: When false, candidates of other garment types may appear, marked outsideGarmentType.
  • id UUID
  • inferredGarmentTypes [String!]!
  • noneFitNotes String
  • noneFitReason SizeChartNoneFitReason
  • outcome SizeChartMatchOutcome!
  • pickedSizeChartId UUID
  • resolvedAt Date

SizeChartRow

One point of measure on a size chart. All centimetre fields are integers in hundredths of a cm.

Fields:

  • adjustment SizeChartAdjustment: This chart's change at the base size. Null when untouched.
  • baseHundredths Int: Value at the base size before any adjustment, in hundredths of a cm. Null on an increment row.
  • baseProvenance SizeChartProvenance!: Where baseHundredths came from. STANDARD_SPEC equals the block; anything else moved from it in an earlier chart.
  • blockBaseHundredths Int: The base value in the uploaded chart this row descends from, as it was when copied. Show a difference from baseHundredths as 'from the block as imported', not as a live comparison.
  • code String!
  • convention PomConvention!: HALF rows are measured flat, edge to edge: half the girth. When a designer edits one, show the full girth (value × 2) live next to the input, so '4 cm wider around' is entered as +2.00 and never +4.00. The backend does not check this.
  • gradeDeltaHundredths [Int!]!: Grade step per size relative to the base size, in the chart's size order. 0 at the base.
  • id UUID
  • origin String: Where the measurement is taken from. Two rows with the same code and different origins are different measurements and must not be compared.
  • position Int!
  • rowKey String!: CODE[@origin]. The only way to address a row in a mutation; a bare code is ambiguous on most charts.
  • sourceLabel String!: The row name as the customer's sheet writes it.
  • toleranceMinusHundredths Int
  • tolerancePlusHundredths Int
  • toleranceRaw String: The tolerance as the source wrote it.
  • toleranceState SizeChartToleranceState!: NONE: the source gave none. UNREADABLE: the source claimed one we could not read; show toleranceRaw as a warning, never as a limit and never as none. PARSED: use the bounds.
  • valuesHundredths [Int!]: The value at every size, in hundredths of a cm, in the chart's size order: base + adjustment + grade step. Null on an increment row.

Skill

Reusable instruction that tells the agent how to approach batch work

Fields:

  • body String!
  • createdAt Date
  • id UUID
  • teamDomain String!
  • title String!
  • updatedAt Date

SpecStepError

One step of a Spec that did not succeed. The delivered image is still the best available result.

Fields:

  • code String!: Why, as a stable machine code: crop_does_not_fit (the subject sits too close to an edge for the crop asked for), no_person (nothing was found to measure against), no_landmarks (the face could not be located for an eye-line crop), segmentation_failed (the model call failed after its retries), config_invalid (the perspective's crop settings cannot be applied to this image), internal (an unexpected error). Phrase these for the customer as what happened to the FILE, e.g. crop_does_not_fit reads as "delivered uncropped".
  • step String!: Which step failed: correction or crop.

VideoButton

Interactive button for product videos

Fields:

  • description String!
  • label String!

WardrobeItem

A styling piece the team completes looks with. Defined by not being what the shot is of, not by whether the team sells it.

Fields:


WardrobeItemImage

One photograph of a wardrobe article, from one angle

Fields:

  • createdAt Date
  • id UUID
  • imageDescription String
  • imageKey String!
  • imageUrl String!: Resolved CDN URL of the photograph
  • viewType ViewType!
  • wardrobeItemId UUID!

Workflow

An autonomous workflow definition: a name plus Markdown instructions the planner decomposes into steps.

Fields:

  • createdAt Date
  • id UUID
  • instructions String!: The workflow as Markdown. Edited by the agent, not a form.
  • name String!
  • teamDomain String!
  • updatedAt Date

WorkflowRun

One execution of a Workflow. Holds the committed plan, a cursor over it, what it's parked on, and per-step outputs. Poll this while non-terminal to watch progress.

Fields:

  • awaitingStepId String: The plan step currently being worked or waited on (the cursor). Null when the run is terminal.
  • batchId UUID: The batch this run operates on (UC1). Null for workflows that aren't batch-scoped.
  • completedStepIds [String!]: Step ids finished so far (the set behind the cursor).
  • createdAt Date
  • id UUID
  • lastError String: Why the run stopped or failed, when applicable.
  • plan [WorkflowStep!]: Ordered steps, committed once at run start. Null until planning completes.
  • status WorkflowRunStatus!: RUNNING, WAITING_FOR_TASKS (parked on a media-task wait-set or the batch's QA), COMPLETED, FAILED, or STOPPED (agent stopped the run).
  • stepResultsJSON String: JSON-encoded map of stepId → the small output that step returned (the only cross-step memory). Parse client-side. Null until a step has produced output.
  • updatedAt Date
  • waitOnEvaluations Boolean!: True when the parked step is waiting on the batch's quality-check (QA) tasks, derived from the run's batch.
  • waitingForTaskIds [UUID!]: The media-generation tasks the parked step is waiting on (the declared wait-set). Null unless parked on a declared set.
  • workflow Workflow!: The workflow definition this run executes.
  • workflowId UUID!

WorkflowStep

One concrete step in a workflow run's plan. Committed once at run start, read-only thereafter. What (if anything) the run waits on after a step is decided at execute time, not by the step.

Fields:

  • description String!
  • id String!: Stable slug, e.g. "step-1". Never reused or reordered within a run.
  • name String!