Types
All GraphQL object types the API returns, in alphabetical order.
AmendMediaPlanResult
Fields:
adsAddedInt!adsApprovedInt!: Ads SET_APPROVAL approved. Ads it skipped as not ready are in notes, with the reason.adsUnapprovedInt!: Ads SET_APPROVAL un-approved on purpose. Not counted in approvalsWithdrawn.approvalsWithdrawnInt!: Approved ads this amendment changed, which are no longer approved and need approving again. Tell the person.cardsChangedInt!cardsRemovedInt!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.planMediaPlan!
AmendPlanResult
Result of amendPlan: counts of updated, added, and removed draft records
Fields:
addedInt!removedInt!updatedInt!
Batch
A unit of work grouping images, skills, and a plan for batch creation
Fields:
campaignImageCountInt!: Number of CampaignImages in this batch (tile overview count)createdAtDateidUUIDinputImages[BatchInputImage!]!: Product images uploaded for this batchinstructionsStringisGeneratedBoolean!: True once every item in the batch (studio + campaign) has finished generating. Derived from task state; unlikestatus, 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.productStudioCountInt!: Number of ProductStudios in this batch (tile overview count)referenceSheetFileNameString: 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.referenceSheetUrlString: 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.shootTypeShootType: Creation-time choice of what this batch produces; a hint for the plan board and planner, not a constraintskills[Skill!]!: Skills referenced by this batchstatusBatchStatus!teamDomainString!updatedAtDate
BatchInputImage
Uploaded input image for a batch, scanned via Gemini pipeline
Fields:
batchIdUUID!createdAtDatefileNameString!filenameViewString: 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 againstviewTypeto flag scan-versus-filename disagreements.idUUIDimageUrlString!productDescriptionStringproductKeyString: 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.productTitleStringupdatedAtDateviewTypeViewType
BillingCostSummary
Aggregated cost breakdown for the requesting team over a date range; powers the cost-overview chart.
Fields:
byFeature[BillingFeatureCostBucket!]!fromDateDate!generationCentsInt!releaseCentsInt!toDateDate!totalCentsInt!
BillingFeatureCostBucket
Per-feature cost slice within a BillingCostSummary; one bar in the cost-overview chart.
Fields:
featureString!generationCentsInt!releaseCentsInt!totalCentsInt!
BillingLedgerEntry
One entry in the billing ledger.
Fields:
aiModelStringbalanceAfterCentsInt!costCentsInt!createdAtDate!deltaCentsInt!entryDescriptionStringidUUID!kindString!outputCountInt!outputUnitOutputUnit: 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.pricingVersionStringusageTypeString
BrandAsset
A reusable file a team puts on its ads, a logo first. PNG only.
Fields:
archivedAtDatecreatedAtDatedarkGroundImageKeyString: The optional PNG for dark grounds. Upload through POST /api/brand-assets/{id}/dark-ground-version/upload.defaultSizeFloat!: Fraction of the frame's shorter edge taken by the logo's longer side, when an ad sets no size.heightInt!idUUIDimageKeyString!: The PNG for light grounds, and the only version when there is one.minimumSizeFloat!slugString!: The handle the planning agent uses.titleString!widthInt!
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:
bandPositionHeadlineBandPositionbandSizeFloat: Band height as a fraction of the frame height. Null unless the ground is SOLID_BAND.copySurfaceHeadlineSurface: Whether the copy sits in the band or on the photo. Null unless the ground is SOLID_BAND.fillColorString: #RRGGBB fill of the band or panel. Decides the ink.groundHeadlineGround!idUUIDimageCopyLinesImageCopyLines!: Which lines of copy images with this treatment carry. The scorer, generation and the renderer use only these.presetKeyStringslugString!: The handle the planning agent uses, such as band-bottom-white.titleString!
BrandMemory
Core content model for the Brand Identity feature.
Fields:
brandIdentityString!brandNameString!copywritingInstructionsString: How the brand writes. Followed by media planner copy generation, beneath a plan's own brief.createdAtDatefashionModelInstructionsStringidUUIDphotoStyleInstructionsStringtargetGroupInstructionsStringteamDomainString!updatedAtDate
Campaign
Named container for organizing single shots and group shots
Fields:
campaignImages[CampaignImage!]!createdAtDategroupShots[GroupShot!]!idUUIDnameString!shootingLocationRevisionShootingLocationRevision: Default location used by campaign images at generation time. Group shots fall back to this if they don't set their own.teamDomainString!updatedAtDate
CampaignImage
Campaign image for marketing content creation
Fields:
aspectRatioAspectRatiobatchBatch: Parent batch if this is a draft campaign image (non-null means part of a plan)campaignCampaigncreatedAtDateerrorMessageStringfashionModelRevisionFashionModelRevisiongeneratedImages[CampaignImageResult!]!includeArchivedBooleanfavoritesOnlyBoolean
guidanceImageKeyString: Cloudflare R2 key of the guidance reference image, or null when the look has noneguidanceImageUrlString: Displayable URL of the guidance reference image: the lookbook page or mood shot this look should feel like. Attached to generation as a style reference only, never as a product or as the human subject.idUUIDiterations[CampaignImageIteration!]!products[CampaignImageProduct!]!promptStringresources[CampaignImageResource!]!shootingLocationRevisionShootingLocationRevisionstatusContentGenerationStatus!teamDomainString!thumbnailUrlString: Image key of the newest non-rejected result, derived livetitleString!updatedAtDate
CampaignImageIteration
Campaign image iteration with feedback loop
Fields:
campaignImageIdUUID!createdAtDatefeedbackStringidUUIDpromptString!results[CampaignImageResult!]!
CampaignImageProduct
Product associated with campaign image
Fields:
campaignImageIdUUID!createdAtDateidUUIDisStylingPieceBoolean!: True when this row is a styling piece the look is completed with, rather than part of what the shot is ofproductDescriptionStringproductIdStringproductImageString!productImageIdString!productTitleStringwardrobeItemIdUUID: 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:
campaignImageIdUUID!contentString!createdAtDateidUUIDnameString!purposeCampaignImageResourcePurpose!
CampaignImageResult
AI-generated campaign image result
Fields:
aspectRatioAspectRatiocampaignImageCampaignImage!campaignImageIdUUID!createdAtDatedownloadableImageUrlString: The stored file of the latest media release as generated, with no sRGB profile and no AI-provenance statement. To deliver the image, useexportImageUrl.editedImageUrlString: DEPRECATED: use 'images' / 'latestImage'. URL of the most recent photo-editor save (legacy single-slot field).exportImageUrlString: 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.favoriteBoolean!: Whether the user has marked this result as a favoriteidUUIDimageKeyString!: Cloudflare R2 key for the generated imageimages[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.isPreviewBoolean!: True when this is a low-res preview render (preview mode). Preview results are generation-free and cannot be released or downloaded:releaseCampaignImageResultwill reject them. Hide release/download and show a preview badge in the UI; to get a final, re-run generation withpreview: false.iterations[CampaignImageIteration!]!latestImageString: Server-side resolution of the most recent stage: the newest entry in the image history. Use this when you just want 'the current image'; useimagesfor the full history.latestMediaReleaseMediaRelease: Most recent media release for this resultmediaGenerationTaskMediaGenerationTask: The media generation task that produced this resultmediaReleases[MediaRelease!]!: All media releases for this resultmodelStringpromptString!updatedAtDateurlString!: 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:
createdAtDategptImage25QualityGptImage25Quality!: 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.idUUIDteamDomainString!updatedAtDateuseGemini3ProBoolean!useGptImage25Boolean!
CardLogo
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:
brandAssetIdUUID!imageKeyString!: The file to draw on this card: the dark-ground version when the ground under the logo is dark and one exists.slotBrandAssetSlot!versionBrandAssetVersion!x0Float!x1Float!y0Float!y1Float!
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:
maxCharactersInt!slotMediaCopySlot!
CopySlotTexts
One slot of copy with its languages. Stored as a row per language, shaped as a map here.
Fields:
slotMediaCopySlot!texts[LocalizedCopy!]!
CreateBillingPortalSessionResponse
Stripe Customer Portal session for invoice and billing management. Frontend redirects the top window to url.
Fields:
urlString!
CreateShopifyTopUpChargeResponse
Shopify one-time charge for a top-up. Frontend redirects the merchant to confirmationUrl.
Fields:
confirmationUrlString!purchaseIdString!
CreateTopUpCheckoutSessionResponse
Stripe Checkout session for a VAT-compliant top-up. Frontend redirects the top window to url.
Fields:
sessionIdString!urlString!
CreateTopUpIntentResponse
[Deprecated] Stripe PaymentIntent for a PAYG top-up. Frontend confirms with clientSecret. Replaced by CreateTopUpCheckoutSessionResponse.
Fields:
clientSecretString!paymentIntentIdString!
CreditBalanceResponse
Current PAYG credit balance for a team.
Fields:
balanceCentsInt!currencyString!
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.idUUID!isPAYGBoolean!teamDomainString!
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:
baseRevisionIdUUIDdeterministic[String!]!effectiveSetupDesignerEffectiveSetup!fingerprintStringneedFromComposer[DesignerComposerRequest!]!rebuildPersonBaseBoolean!regenerates[OutputSlot!]!viewDetails[DesignerViewDetails!]!: Placed details per view. Every render prompt for a view listed here must bind each detail's marker colour to its artwork by label; generateDesignerRevision refuses one that does not name them.
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:
briefString: Narrative anchor for the collection (customer, mood, references). Agent-authorable. Injected as additional prompt context into every DI generation in the collection.createdAtDatedesignerInstances[DesignerInstance!]!: Live designs in this collection. Archived designs are left out; unarchiving one returns it here.idUUIDpatternRevisions[PatternRevision!]!seasonStringstatusDesignerCollectionStatus!teamDomainString!titleString!updatedAtDate
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:
descriptionString!fabricSwatchUrlStringoutfitContextStringoverlayUrlStringviewDesignerPersonView!
DesignerComposerDetail
One placed detail as the composer needs it to write a render prompt.
Fields:
artworkKeyString!artworkUrlStringlabelString!: 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.markerColorDesignerMarkerColor!: 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:
contextDesignerComposerContext!editFromKeyStringkindDesignerComposerKind!slotOutputSlot!
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:
collectionBriefStringcollectionIdUUIDdescriptionStringfabricMaterialHintString: Source pattern prompt or user intent for composition, not visual verification of the generated swatch.fabricRefUUIDfabricStatusContentGenerationStatusfabricSwatchUrlStringfashionModelRevisionIdUUIDoutfitContextStringplacedDetails[DesignerPlacedDetail!]: The detail set the generation will freeze: the change set's details with marker colours assigned, or the base's set carried forward.sourcePatternRevisionIdUUID
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:
baseFabricIdUUID: The fabric this one iterates from, if it was an explicit fabric edit.createdAtDatedesignerInstanceIdUUID!errorMessageStringgenerationModelStringidUUIDimageKeyStringimageUrlString: Resolved CDN URL of the frozen swatch. Null while the fabric is still generating.reinterpretationFloat!: 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.sourcePatternRevisionIdUUID: The PatternRevision this fabric was materialised from (provenance). The frozen swatch image lives on imageKey, independent of later edits to the shared Pattern.statusContentGenerationStatus!
DesignerInstance
Brandmachine Designer instance: owns inspiration resources, revisions, selected patterns, and the chosen fashion model used across the whole instance
Fields:
activeFabricDesignerFabric: The active fabric (the swatch renders use). Null until established.activeFabricIdUUID: Designer v4 'fabric' layer pointer: the DesignerFabric whose swatch renders currently composite. Null until a fabric is established.archivedAtDate: 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.createdAtDatedescriptionString: 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).fashionModelRevisionIdUUIDidUUIDlatestSizeChartMatchRunSizeChartMatchRun: The newest matcher shortlist for this design, whatever its outcome.outfitContextString: 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.sizeChartSizeChart: This design's size chart, copied from a chart in the library. Null until one is created with createDesignerSizeChart.teamDomainString!thumbnailUrlString: Image key of the newest revision's front photo, derived livetitleString!updatedAtDate
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:
createdAtDatedescriptionString: Gemini Vision description of an image-backed resource, written once at upload. Null for text-only resources. Replaces the v2analysisfield.designerInstanceIdUUID!idUUIDimageKeyStringlabelString!textString
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:
annotationOverlayKeyString: Cloudflare bucket key of the painted composite (v3 Cluster A) when this revision was triggered by paint-and-regenerate. Null otherwise.annotationOverlaySourceSlotOutputSlot: Which slot of the base revision the designer painted on (FRONT or BACK). Travels with annotationOverlayKey; null when no overlay.annotationOverlayUrlString: 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/.backFlatKeyStringbackFlatUrlString: Resolved public CDN URL of the BACK technical drawing (opt-in flat). Null when backFlatKey is null. Use for multimodal agent reads.backPhotoKeyStringbackPhotoUrlString: Resolved public CDN URL of the BACK photo, derived from backPhotoKey. Null when backPhotoKey is null. Same use as frontPhotoUrl.baseRevisionIdUUIDcreatedAtDatedesignerInstanceDesignerInstance: Owning design with its current title, loaded in a team-scoped batch. Renames are reflected on historical revisions too.designerInstanceIdUUID!errorMessageStringfavoriteBoolean!frontFlatKeyStringfrontFlatUrlString: Resolved public CDN URL of the FRONT technical drawing (opt-in flat). Null when frontFlatKey is null. Use for multimodal agent reads.frontPhotoKeyStringfrontPhotoUrlString: 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.).frozenDescriptionString: 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.frozenFashionModelRevisionIdUUID: The fashion model revision this revision's person base used (fixed per design). Null on a legacy row.frozenOutfitContextString: 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.generationProvenanceStringidUUIDintentTagStringlabelStringpersonBackKeyString: Designer v4 'person' layer: BACK dressed-base key. Null until generated.personBackUrlString: Resolved CDN URL of the BACK dressed base. Null when personBackKey is null.personFrontKeyString: 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.personFrontUrlString: Resolved CDN URL of the FRONT dressed base. Null when personFrontKey is null.pinnedFabricIdUUID: 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.resolvedFabricKeyString: The fabric swatch key a render actually composited, stamped at fire time. Null until a render fires or when the garment has no fabric.resolvedFabricUrlString: Resolved CDN URL of the fabric swatch this revision composited, from resolvedFabricKey. Null when resolvedFabricKey is null.shapeBackKeyString: Designer v4 'shape' layer: BACK grey-puppet key. Null on legacy revisions and until generated.shapeBackUrlString: Resolved CDN URL of the BACK grey puppet. Null when shapeBackKey is null.shapeFrontKeyString: 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.shapeFrontUrlString: Resolved CDN URL of the FRONT grey puppet. Null when shapeFrontKey is null.snapshotDesignerInstanceRevisionSnapshotstatusContentGenerationStatus!userRequestString
DesignerInstanceRevisionSlotSnapshot
Per-slot frozen record of prompt + input files for a revision
Fields:
inputKeys[String!]!promptString!resourceIDs[UUID!]!slotOutputSlot!
DesignerInstanceRevisionSnapshot
Frozen inputs + per-slot prompts for a DesignerInstanceRevision
Fields:
resourceIDs[UUID!]!slots[DesignerInstanceRevisionSlotSnapshot!]!
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:
artworkKeyString!artworkUrlString!: Resolved CDN URL of the artwork image, from artworkKey.backDesignerPlacementfrontDesignerPlacementidUUID!labelString!: The name the render prompt gives this detail's artwork image. Unique per revision.markerColorDesignerMarkerColor!: Backend-assigned marker colour, stable for this detail across revisions.sourceResourceIdUUID!: 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:
heightFloat!widthFloat!xFloat!yFloat!
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!]!markedPuppetUrlString: 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.viewDesignerPersonView!
ExportMediaPlanResult
Fields:
alreadyRenderingInt!: Renders skipped because an earlier export of the same image is still rendering.failedInt!: 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.planMediaPlan!queuedInt!: Renders sent to the renderer.
FashionModel
Fashion model for AI-generated content creation
Fields:
createdAtDategenderFashionModelGender!idUUIDnameString!revisions[FashionModelRevision!]!statusContentGenerationStatus!teamDomainString!updatedAtDate
FashionModelCasting
Casting session that generates fashion model candidates
Fields:
createdAtDategenderFashionModelGender!idUUIDpromptString!results[FashionModelCastingResult!]!teamDomainString!updatedAtDate
FashionModelCastingResult
Single image result from a fashion model casting
Fields:
FashionModelRevision
Immutable snapshot of an iterative edit on a fashion model
Fields:
createdAtDatefashionModelFashionModel!fashionModelIdUUID!favoriteBoolean!fullPortraitKeyStringgenerationModelStringidUUIDlabelStringpromptStringresourcesFashionModelRevisionResourcessetCardKeyStringuserInputString!
FashionModelRevisionResources
Structured resources for a fashion model revision
Fields:
beardStringbodyShapeStringdescriptionStringhairstyleStringmakeupString
FileNameConvention
How a team's uploaded filenames are read and how delivered filenames are written
Fields:
exportPatternStringisDefaultBoolean!: 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:
problems[FileNameConventionProblem!]!rows[FileNamePreviewRow!]!unmatchedCountInt!: How many sampled files the proposed convention cannot read. A jump means a template was tightened too far.
FileNameConventionProblem
One reason a filename convention cannot be stored
Fields:
codeFileNameConventionProblemCode!: Stable machine name, for styling or grouping without reading the sentence.messageString!: Written for the person building the convention. Display this.templateIndexInt: 1-based, matching the numbering insidemessage, 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:
nameString!valueString!
FileNameFieldRule
Fields:
countIntfieldString!kindFileNameFieldConstraintKind!roleFileNameFieldRole!: What this field means: part of product identity, the view, or neither.values[String!]
FileNamePreviewRow
Fields:
changedBoolean!: True when saving would change this file's product identity. This is the column that matters.currentProductKeyString: What this file resolves to under the currently saved convention.exportFileNameStringfields[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.fileNameString!matchedTemplateInt: 1-based index of the template that matched, matching how templates are numbered in problem messages. Null when nothing matched.productKeyString: 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.viewTokenString: 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.viewTypeViewType
FileNameTemplate
Fields:
fields[FileNameFieldRule!]!: Only the fields that declare something. A field named in the pattern but absent here is an unconstrained identity field.patternString!
FileNameViewCodeMapping
Fields:
codeString!viewTypeViewType!
GroupShot
Multi-model composite image assembled from single shots
Fields:
aspectRatioAspectRatiocampaignCampaign!campaignIdUUID!createdAtDateerrorMessageStringidUUIDintermediateRenders[GroupShotIntermediateRender!]!promptStringresults[GroupShotResult!]!favoritesOnlyBoolean
shootingLocationRevisionShootingLocationRevisionsingleShots[GroupShotSingleShot!]!statusContentGenerationStatus!thumbnailUrlString: Image key of the newest non-rejected composite result, derived liveupdatedAtDate
GroupShotIntermediateRender
Per-person intermediate render for group shot pipeline
Fields:
campaignImageCampaignImage!campaignImageIdUUID!createdAtDateerrorMessageStringgroupShotIdUUID!idUUIDimageKeyStringstatusContentGenerationStatus!updatedAtDate
GroupShotResult
Final composite image from the group shot pipeline
Fields:
aspectRatioAspectRatiocreatedAtDatedownloadableImageUrlStringeditedImageKeyStringexportImageUrlString: 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.favoriteBoolean!: Whether the user has marked this result as a favoritegroupShotIdUUID!hiddenAtDateidUUIDimageKeyString!latestMediaReleaseMediaReleasemediaReleases[MediaRelease!]!modelStringupdatedAtDate
GroupShotSingleShot
Link between a group shot and one of its single shots
Fields:
campaignImageCampaignImage!campaignImageIdUUID!createdAtDategroupShotIdUUID!idUUID
LocalizedCopy
One line in one language.
Fields:
approvedAtDateapprovedByStringlocaleString!originMediaCopyOrigin!: GENERATED or EDITED. Generation never overwrites an EDITED or approved line unless asked to regenerate.textString!
LuminanceGrid
Relative luminance over one source image, as a coarse grid.
Fields:
dataString!: 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.heightInt!widthInt!
MaterializePlanResult
Result of materializePlan — counts of created draft records
Fields:
campaignImagesCreatedInt!productStudiosCreatedInt!
MediaFormat
One image specification: ratio, exact pixels, byte budget, safe area, and the copy limits that belong to a card.
Fields:
aspectRatioString!copyLimitsSourcedBoolean!descriptionMaxCharsIntheadlineMaxCharsIntidUUIDmaxBytesIntoverlaysAllowedBoolean!: 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.safeAreaBottomFloatsafeAreaLeftFloatsafeAreaRightFloatsafeAreaTopFloatsafeZonePublishedBoolean!: True when the safe areas are the platform's own published figures, false when they are our conservative default.slugString!targetHeightInt!targetWidthInt!titleString!
MediaGenerationTask
Tracks media generation tasks for notification center
Fields:
campaignImageCampaignImage: Parent CampaignImage (non-null only for CampaignImage tasks)campaignImageIdUUID: FK to the parent CampaignImagecampaignImageResults[CampaignImageResult!]!: CampaignImage results produced by this taskcompletedAtDatecreatedAtDatedesignerInstanceRevisionDesignerInstanceRevision: Parent DesignerInstanceRevision (non-null only for DesignerRevisionSlot tasks; one task per slot, up to four tasks point at the same revision)designerInstanceRevisionIdUUID: FK to the parent DesignerInstanceRevisionerrorMessageStringfashionModelCastingFashionModelCasting: Parent FashionModelCasting (non-null only for FashionModelCasting tasks)fashionModelCastingIdUUID: FK to the parent FashionModelCastingfashionModelRevisionFashionModelRevision: Parent FashionModelRevision (non-null only for FashionModelRevision tasks)fashionModelRevisionIdUUID: FK to the parent FashionModelRevisiongroupShotGroupShot: Parent GroupShot (non-null only for GroupShot tasks)groupShotIdUUID: FK to the parent GroupShotidUUIDmediaPlanIdUUID: The media plan this task works on: an export, a copy run, or segmenting one of its sources.patternRevisionPatternRevision: Parent PatternRevision (non-null only for PatternRevision tasks)patternRevisionIdUUID: FK to the parent PatternRevisionphaseString: 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.productStudioProductStudio: Parent ProductStudio (non-null only for ProductStudio tasks)productStudioIdUUID: FK to the parent ProductStudio (non-null only for ProductStudio tasks)productStudioOutputs[ProductStudioOutput!]!: ProductStudio outputs produced by this taskproductStudioPerspectiveProductStudioPerspective: ProductStudio perspective being generated (non-null only for ProductStudio tasks)productStudioPerspectiveIdUUID: FK to the ProductStudio perspective being generatedproductVideoProductVideo: Parent ProductVideo (non-null only for ProductVideo tasks)productVideoIdUUID: FK to the parent ProductVideoshootingLocationShootingLocation: Parent ShootingLocation (non-null only for ShootingLocation tasks)shootingLocationIdUUID: FK to the parent ShootingLocationsizeChartAnnotationIdUUID: FK to the parent SizeChartAnnotationsizeChartDesignerInstanceIdUUID: The design whose size chart an annotation task draws, for navigating from the tasks panel. Non-null only for size chart annotation tasks.slotOutputSlot: Designer output slot derived from its standardized task title. Null for other task types or unrecognized titles.statusContentGenerationStatus!teamDomainString!titleString!typeTaskType!updatedAtDate
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:
channelMediaChannel!copyLimitsSourcedBoolean!: 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.ctaMaxCharsIntdescriptionMaxCharsIntheadlineMaxCharsIntidUUIDmaxCardsInt!minCardsInt!placementCodeString!primaryTextMaxCharsIntslugString!titleString!
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.copyGeneratingSinceDate: Set while copy is being generated; poll until it clears.copyGenerationErrorStringcreatedAtDateheadlineTreatmentBrandHeadlineTreatmentheadlineTreatmentIdUUID: The plan's default treatment. Null means plain type over the photo.idUUIDinstructionsStringlocales[String!]!: BCP-47 tags this plan's copy is written in, the first being the main one.nameStringplacements[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!]!teamDomainString!updatedAtDate
MediaPlanBrandAsset
One logo in a plan's default set.
Fields:
brandAssetBrandAsset!brandAssetIdUUID!positionInt!sizeFloat: Null uses the asset's default size.
MediaPlanRender
One card's image in one language, rendered with its copy and logos.
Fields:
cardIdUUID!failureMediaPlanRenderFailurefileMediaPlanRenderFile: Set only while RENDERED.finishedAtDatefitMediaPlanRenderFit: How the text fitted. Null on a reused file whose first render is no longer known.idUUID!localeString!requestedAtDate!statusMediaPlanRenderStatus!: A render queued for longer than the renderer can take reads as FAILED with TIMED_OUT.warnings[MediaPlanRenderWarning!]!: Delivered with the file, worth a look: NEAR_FLOOR, HYPHENATED, FIT_NOT_STRICT, HYPHENATION_UNAVAILABLE.
MediaPlanRenderFailure
Fields:
characters[String!]!: The characters the font cannot draw, for GLYPHS_MISSING.codeMediaPlanRenderFailureCode!messageString!slotMediaCopySlot: The line the failure is about, for TEXT_DID_NOT_FIT and GLYPHS_MISSING.
MediaPlanRenderFile
Fields:
bytesIntheightIntkeyString!reusedBoolean!: True when an identical render already existed and nothing was drawn again.urlString!: 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.widthInt
MediaPlanRenderFit
Fields:
atFloorBoolean!: True when the headline only fitted at the smallest size allowed.headlineSizePxFloat!hyphenatedBoolean!linesInt!
MediaPlanSource
One finished output the human selected, owned as a copy so editing or deleting the original cannot change what was planned.
Fields:
campaignImageIdUUID: 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.faceBoxNormalisedBox: Where the face is in the source. The layout scorer refuses any headline band that touches it.hasFaceBoxBoolean!: 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.hasPersonBoxBoolean!idUUIDisMeasuredBoolean!: Whether the tone measurement landed.luminanceGridLuminanceGridpersonBoxNormalisedBoxpositionInt!sourceAspectRatioStringsourceHeightIntsourceIdUUID!sourceKeyString!: The handle the planning agent sees, such as look-1. The agent never handles a UUID.sourceMediaKeyString!sourceResolutionStringsourceTypeString!sourceWidthInt
MediaRelease
A media release of a generated asset (ProductStudioOutput, CampaignImageResult, etc.)
Fields:
campaignImageResultCampaignImageResult: The campaign image result this release belongs to, if any. Loaded with the release inreleasedImages.createdAtDate: When the asset was first released.exportImageUrlString: 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.groupShotResultGroupShotResult: The group shot result this release belongs to, if any. Loaded with the release inreleasedImages.idUUIDobjectKeyString!productStudioOutputProductStudioOutput: The product studio output this release belongs to, if any. Loaded with the release inreleasedImages.teamDomainString!updatedAtDate: When the release last changed: first release, re-release, or an edit saved after release.upscaleFactorFloat
NormalisedBox
A rectangle as fractions of the frame it sits in, centre-first.
Fields:
cxFloat!cyFloat!hFloat!wFloat!
OnboardingSampleDataResult
Response for onboarding sample data creation
Fields:
createdBoolean!
OutputImage
One entry in an output's chronological image history (Product Studio outputs and campaign image results).
Fields:
createdAtDate!floorStatusString: 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.keyString!: R2 key (or full URL for seed assets) of this variant.shadowFlagString: 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,keypoints 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.typeOutputImageType!upscaleFloat: 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.urlString!: Full CDN URL for this variant.
Pattern
Shop-level, agent-iterable pattern asset used by Designer Instances. Produces a single image per revision.
Fields:
createdAtDateidUUIDinputReferences[PatternInputReference!]!: Pattern-level reference library. Persistent; the agent flattens these into PatternRevision.inputs on every generation call.nameString!repeatHorizontalBoolean!repeatVerticalBoolean!revisions[PatternRevision!]!statusContentGenerationStatus!teamDomainString!updatedAtDate
PatternInputReference
Persistent inspiration reference attached to a Pattern. Label + image. Uploaded via POST /api/patterns/references.
Fields:
PatternRevision
Immutable output of one iteration on a Pattern.
Fields:
baseRevisionIdUUIDcreatedAtDateerrorMessageStringfavoriteBoolean!generationModelStringidUUIDimageKeyStringinputs[PatternRevisionInput!]labelStringpatternPattern!patternIdUUID!promptStringstatusContentGenerationStatus!userInputString
PatternRevisionInput
One labelled reference snapshotted onto a PatternRevision at generation time.
Fields:
imageKeyString!labelString!
Plan
Fields:
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!]!cropHFloatcropWFloatcropXFloatcropYFloatfaceFullyInsideBoolean!: 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.fillColorString: #RRGGBB of the band or panel this card was laid out with. Null when it has neither.formatMediaFormatheadlineGroundHeadlineGround!: 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.idUUIDinkStringlayoutEditedAtDate: 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.layoutStateMediaLayoutState!logos[CardLogo!]!: The ad's logos as this card shows them. Empty until the card is laid out.measuredContrastFloat: Advisory, never a gate. Real contrast depends on the type treatment, which is downstream of a brand type spec.mediaFormatIdUUID!mediaPlanSourceIdUUID!methodMediaAdaptationMethod!notesStringphotoX0Float: 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.photoX1FloatphotoY0FloatphotoY1FloatpositionInt!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.zoneNameStringzoneX0FloatzoneX1FloatzoneY0FloatzoneY1Float
PlannedPlacement
One advertisement. Approved as a unit, because approving three of five carousel cards is not a state that means anything.
Fields:
approvedAtDateapprovedByStringbrandAssets[PlannedPlacementBrandAsset!]!: The logos on this ad, in order, with the slot each sits in.brandAssetsOverriddenBoolean!: 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.headlineTreatmentBrandHeadlineTreatmentheadlineTreatmentIdUUID: This ad's own treatment. Null inherits the plan's.idUUIDmediaPlacementIdUUID!notesStringplacementMediaPlacementpositionInt!readyToApproveBoolean!: 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:
brandAssetBrandAsset!brandAssetIdUUID!positionInt!sizeFloat: Null uses the asset's default size.slotBrandAssetSlot: Where the logo sits on every card of this ad. Null when no slot fits every card.slotEditedAtDate: 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:
chargeCentsInt!currencyString!labelString!: Merchant-facing name for this charge, e.g. "GPT Image 2.5 (high)". Render this; do not derive a name from usageType.outputUnitOutputUnit!: What chargeCents buys one of: IMAGE, VIDEO or SECOND. Product video generation is priced per second of video.pricingVersionString!tierPricingTier!: Which half of the pricing model this charge belongs to: GENERATION per attempt while creating, RELEASE once when a finished asset is exported.usageTypeString!
ProductStudio
Core content model for the ProductStudio feature.
Fields:
batchBatch: Parent batch if this is a draft studio (non-null means part of a plan)createdAtDateexportFileNames[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.fashionModelRevisionFashionModelRevision: The selected fashion model revision for this studio sessionidUUIDinputs[ProductStudioInput!]!: Product inputs for this studio session, sorted by creation date (newest first)isGeneratedBoolean!: 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 sessionincludeArchivedBooleanproductStudioPerspectiveIdUUIDfavoritesOnlyBoolean
statusContentGenerationStatus!stylingResources[ProductStudioStylingResource!]!: Styling instructions per perspective for this studio sessionteamDomainString!: The Shopify team domain this studio belongs totitleStringupdatedAtDate
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.exportCodeString: This perspective's token for delivered filenames, or null if it has none.fileNameString: What this studio would be delivered as for this perspective, with no extension. Null when it cannot be computed, in which caseunavailableReasonsays why.perspectiveIdUUID!perspectiveNameString!unavailableReasonProductStudioExportNameUnavailableReason: Why there is no name. Present exactly whenfileNameis null.
ProductStudioHomeCard
A single card on the Home view, carrying everything the UI renders for one studio.
Fields:
perspectivesGeneratedInt!: Distinct perspectives this studio has at least one output for.perspectivesPickedInt!: Subset of perspectivesGenerated where at least one output is favorited.reviewStateStudioReviewState!studioProductStudio!thumbnailUrlString: 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:
createdAtDateidUUIDinpaintedResultString: Final inpainted image URL for this combinationinputIdUUID!: The ProductStudioInput this result belongs toisCompleteBoolean!: Whether this inpaint result is completeisReadyForInpaintingBoolean!: Whether this record is ready for inpaintingoutputIdUUID!: The ProductStudioOutput this result belongs tosceneMaskString: Scene mask URL for this input in this specific scene
ProductStudioInput
Individual product input within a ProductStudio session.
Fields:
createdAtDatefileNameString: 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.filenameViewString: The raw view token the filename declares, before translation through the team's view codes. Null when nothing matched.idUUIDinpaintResults[ProductStudioInpaintResult!]!: Inpaint results for this input across all outputsisHeroBoolean!: Marks this input as a focus / hero product. Perspectives with useHeroOnly=true filter generation down to hero inputs only.isStylingPieceBoolean!: 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.productDescriptionString: Detailed product descriptionproductDetailPromptString: Guidance prompt to guide AI image generationproductIdString: Optional Shopify product ID if attached to a productproductImageString!: The uploaded image URL (stored in Shopify after upload)productImageIdString!: The Shopify file ID (GID) for the uploaded imageproductKeyString: 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.productStudioIdUUID!: The ProductStudio this input belongs toproductTitleString: User-provided title/description for this inputviewTypeViewType!: View type of this product input (front, back, other, or cropped)wardrobeItemIdUUID: 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:
completionPercentageFloat!: Returns progress based on which images are availablecorrectedImageUrlString: 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'sbackgroundHexColorexactly. Set only when the perspective carries abackgroundHexColorand correction has completed. Built on top ofimageKeyand remains populated even after a subsequent user edit, so the frontend can show pre-edit state or revert.createdAtDatedownloadableImageUrlString: The stored file of the latest media release as generated, with no sRGB profile and no AI-provenance statement. To deliver the image, useexportImageUrl.editedImageUrlString: 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.evaluationProductStudioOutputEvaluation: 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.exportFileNameString: 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.exportImageUrlString: 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 fromexportFileNameto follow the team's naming convention.favoriteBoolean!: Whether the user has marked this output as a favoritefinalImageUrlString: DEPRECATED: Use 'imageKey' instead. Returns the Cloudflare R2 key for the final composed image.idUUIDimageKeyString: 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 inputsisPreviewBoolean!: True when this is a low-res preview render (preview mode). Preview outputs are generation-free and cannot be released or downloaded:releaseProductStudioOutputwill reject them. Hide release/download and show a preview badge in the UI; to get a final, re-run generation withpreview: false.latestImageString: 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'; useimageswhen you need the full history or before/after views.latestMediaReleaseMediaRelease: Most recent media release for this outputmediaGenerationTaskMediaGenerationTask: The media generation task that produced this output. ItsstatusanderrorMessageare 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'sstepErrorsinstead.mediaReleases[MediaRelease!]!: All media releases for this outputmodelString: Which AI model rendered this output, as the rawAiModelvalue (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.productStudioProductStudio!: Parent ProductStudio sessionproductStudioIdUUID!: The ProductStudio this output belongs toproductStudioPerspectiveIdUUID!: The perspective this output was generated for. Read this directly when you only need the perspective ID; avoid walking throughmediaGenerationTask.productStudioPerspective.idwhich fires per-output N+1 queries.updatedAtDate
ProductStudioOutputEvaluation
Automated quality evaluation of a ProductStudioOutput's raw AI generation, scored against the product input(s) by Gemini.
Fields:
commentString!: One-line human-readable explanation of the score.createdAtDateidUUIDmodelString!: The model id that produced the score, e.g.gemini-3.7-flash.scoreFloat!: 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)aiModelAiModel!: 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.archivedAtDate: When set, the perspective is archived and hidden from the default list.aspectRatioAspectRatiobackgroundHexColorString: 6-character hex color for the studio backdrop (e.g. 'ff0077'), without # prefix. Null means no specific backdrop color.createdAtDateexportCodeString: Token representing this perspective in delivered filenames ("001", "FRONT"). Free-form and never interpreted. Separate fromnameon purpose: download filenames used to be derived from the display name, so renaming a perspective silently renamed every past delivery.groupIdUUID: The rail tab this perspective is filed under, or null for ungrouped. The id only: there is deliberately nogrouprelation 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.guideKeyString: 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.idUUIDisDefaultBoolean!isLockedBoolean!: 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.isProductOnlyBoolean!: When true, generates product-only pack shots without a fashion model.nameString!outputs[ProductStudioOutput!]!plateKeyString: 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.presetKeyPerspectivePresetKey: 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.promptString!qaPromptString: 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 whatpromptdoes.shootingLocationRevisionShootingLocationRevision: Optional generated scene the subject is composited into. When set it replaces the flat backgroundHexColor backdrop and background correction is skipped.shootingLocationRevisionIdUUID: The attached scene (shooting location revision) this perspective renders into, if any. Read this directly when you only need the id.sortOrderInt: 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.specCropString: 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.targetRatioHInt: Free-form target aspect ratio height (e.g. 9 in 7:9). Set with targetRatioW.targetRatioWInt: 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.teamDomainString!updatedAtDateuseHeroOnlyBoolean!: 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:
createdAtDateidUUIDnameString!purposeString: 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.sortOrderInt: 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.teamDomainString!updatedAtDate
ProductStudioSetting
Settings for Product Studio feature customization.
Fields:
ProductStudioStylingResource
Styling instructions for a specific ProductStudio session and perspective
Fields:
createdAtDateidUUIDproductStudioIdUUID!productStudioPerspectiveIdUUID!stylingInstructionsString!
ProductVideo
Core content model for the Product Shorts feature.
Fields:
buttons[VideoButton!]: Array of interactive buttons with labels and descriptionscreatedAtDatedurationSecondsInt!: Length in seconds of the video this row last generated, and the length a regenerate repeats. Generation is billed per second.idUUIDmodelTypeVideoModelType: The AI model used for video generationproductIdStringproductImageStringproductImageIdStringproductTitleStringprogressProgress!: Current progress information for the video generation flowpromptString: Custom prompt for video generationstatusContentGenerationStatus!teamDomainString!: The Shopify team domain this video belongs toupdatedAtDatevideoUrlString: The result of the genai video generation process.
Progress
Progress information for long-running flows
Fields:
messageString!percentageFloat!
ReferenceLook
One look as read off an uploaded looks sheet.
Fields:
descriptionString!: Every garment in the look, top to bottom, with type, colour, fit and any readable print; says so when a slot is absent.idString!: 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:
cursorString: Pass asafteron the next call. Store it after each sync; it is null only when the team has never released an image.hasMoreBoolean!: 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:
heightInt!widthInt!
SetFileNameConventionResult
Fields:
conventionFileNameConvention!problems[FileNameConventionProblem!]!: Empty means it saved. Non-empty means nothing was written andconventionis what remains in force.
ShootingLocation
ShootingLocation for marketing content creation
Fields:
createdAtDateidUUIDrevisions[ShootingLocationRevision!]!teamDomainString!thumbnailUrlString: Image key of the newest revision with a generated image, derived livetitleString!updatedAtDate
ShootingLocationRevision
Immutable snapshot of a shooting location generation cycle
Fields:
createdAtDatefavoriteBoolean!idUUIDimageKeyStringlabelStringmodelStringresourcesShootingLocationRevisionResourcesshootingLocationShootingLocation!shootingLocationIdUUID!userInputString!
ShootingLocationRevisionResources
Structured resources for a shooting location revision
Fields:
extrasStringlightingStringlocationStringmoodString
ShopifyPageInfo
Pagination info for Shopify queries
Fields:
endCursorStringhasNextPageBoolean!
ShopifyProduct
A Shopify product from the Admin API
Fields:
handleString!idString!images[ShopifyProductImage!]!productTypeString!statusString!tags[String!]!titleString!totalInventoryIntvariants[ShopifyProductVariant!]!vendorString!
ShopifyProductImage
A Shopify product image
Fields:
altTextStringheightIntidString!urlString!widthInt
ShopifyProductsResult
Paginated result of Shopify product search
Fields:
pageInfoShopifyPageInfo!products[ShopifyProduct!]!
ShopifyProductVariant
A Shopify product variant
Fields:
idString!inventoryQuantityIntpriceString!skuStringtitleString!
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:
annotationSizeChartAnnotation: The technical drawings with this chart drawn on. Design charts only.baseSizeString!: The size adjustments are made at. Every other size is base plus its grade step.codeString: The customer's identifier for an uploaded spec. Null on design charts.createdAtDatedepartmentString!: The customer's target group, e.g. boys or women. Matching stays inside one department.derivedFromChartIdUUID: The chart this one copied its rows from. May no longer exist.designerInstanceIdUUIDgarmentTypeString!: The customer's own word for the garment type. Not a fixed list: departments and customers use their own vocabulary.idUUIDisCompleteBoolean!: False when any row records grade steps and no absolute value. Such rows print no values and refuse adjustments; show a warning.nameString!patternGroupString: 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.productGroupStringrows[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.sourceSizeChartSource!: UPLOADED: a customer's standard spec, never adjusted. DERIVED: a design's chart, copied from another chart.sourceFileStringsupersededAtDate: Set when a later upload replaced this uploaded chart. Superseded charts stay so design charts can still name them.updatedAtDate
SizeChartAdjustment
A change at the base size on a design chart, in hundredths of a cm.
Fields:
deltaHundredthsInt!provenanceSizeChartProvenance!reasonStringupdatedAtDate
SizeChartAnnotation
A design revision's technical drawings with the size chart's base-size values drawn on.
Fields:
backUrlStringcreatedAtDatedesignerInstanceRevisionIdUUID!: The revision whose technical drawings were annotated.errorMessageStringfrontUrlStringidUUIDisOutOfDateBoolean!: True when the chart changed after this drawing was made (an adjustment). Offer to annotate again.lines[String!]!: The label lines drawn.statusContentGenerationStatus!: COMPLETED once both views landed.
SizeChartMatchCandidate
Fields:
codeStringconfidenceInt!: 1 (unlikely) to 5 (strong). Ranks candidates; never sets a measurement.nameString!outsideGarmentTypeBoolean!: 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.patternGroupString: 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.rankInt!rationaleString!sizeChartIdUUID!
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.createdAtDatedepartmentString!designerInstanceIdUUIDdesignerInstanceRevisionIdUUID!garmentTypeConfidentBoolean!: When false, candidates of other garment types may appear, marked outsideGarmentType.idUUIDinferredGarmentTypes[String!]!noneFitNotesStringnoneFitReasonSizeChartNoneFitReasonoutcomeSizeChartMatchOutcome!pickedSizeChartIdUUIDresolvedAtDate
SizeChartRow
One point of measure on a size chart. All centimetre fields are integers in hundredths of a cm.
Fields:
adjustmentSizeChartAdjustment: This chart's change at the base size. Null when untouched.baseHundredthsInt: Value at the base size before any adjustment, in hundredths of a cm. Null on an increment row.baseProvenanceSizeChartProvenance!: Where baseHundredths came from. STANDARD_SPEC equals the block; anything else moved from it in an earlier chart.blockBaseHundredthsInt: 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.codeString!conventionPomConvention!: 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.idUUIDoriginString: Where the measurement is taken from. Two rows with the same code and different origins are different measurements and must not be compared.positionInt!rowKeyString!: CODE[@origin]. The only way to address a row in a mutation; a bare code is ambiguous on most charts.sourceLabelString!: The row name as the customer's sheet writes it.toleranceMinusHundredthsInttolerancePlusHundredthsInttoleranceRawString: The tolerance as the source wrote it.toleranceStateSizeChartToleranceState!: 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:
SpecStepError
One step of a Spec that did not succeed. The delivered image is still the best available result.
Fields:
codeString!: 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_fitreads as "delivered uncropped".stepString!: Which step failed:correctionorcrop.
VideoButton
Interactive button for product videos
Fields:
descriptionString!labelString!
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:
archivedAtDate: Non-null when the article is hidden from pickers and from the plannercategoryWardrobeCategory!createdAtDateidUUIDimages[WardrobeItemImage!]!styleReferenceStringteamDomainString!titleString!updatedAtDateusageNoteString
WardrobeItemImage
One photograph of a wardrobe article, from one angle
Fields:
createdAtDateidUUIDimageDescriptionStringimageKeyString!imageUrlString!: Resolved CDN URL of the photographviewTypeViewType!wardrobeItemIdUUID!
Workflow
An autonomous workflow definition: a name plus Markdown instructions the planner decomposes into steps.
Fields:
createdAtDateidUUIDinstructionsString!: The workflow as Markdown. Edited by the agent, not a form.nameString!teamDomainString!updatedAtDate
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:
awaitingStepIdString: The plan step currently being worked or waited on (the cursor). Null when the run is terminal.batchIdUUID: 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).createdAtDateidUUIDlastErrorString: Why the run stopped or failed, when applicable.plan[WorkflowStep!]: Ordered steps, committed once at run start. Null until planning completes.statusWorkflowRunStatus!: RUNNING, WAITING_FOR_TASKS (parked on a media-task wait-set or the batch's QA), COMPLETED, FAILED, or STOPPED (agent stopped the run).stepResultsJSONString: 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.updatedAtDatewaitOnEvaluationsBoolean!: 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.workflowWorkflow!: The workflow definition this run executes.workflowIdUUID!
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:
descriptionString!idString!: Stable slug, e.g. "step-1". Never reused or reordered within a run.nameString!