Advanced Strategies
Overview
A Strategy Group is a managed container that coordinates one or more grouped strategies under a single budget, unit cap, and lifecycle. Each grouped strategy targets products dynamically through filter criteria and fair-value variance, so it stays current as the catalog changes.
Use Strategy Groups when you want to:
- Define a single budget that's shared across many filter slices (e.g. one $100k group spanning every PSA-graded Pokémon card meeting a confidence floor)
- Update pricing once and have it propagate to every underlying bid
- Pause, resume, or delete a whole portfolio in a single call
- Cap per-asset concentration without touching individual bids
Concepts
Group
A group owns the shared lifecycle and risk envelope:
- Budget —
maxGroupSpendCentscaps total spend across all child strategies - Unit cap —
maxUnitQuantitycaps total units filled across all child strategies - Per-product fill cap —
maxFillsPerConfigcaps how many times a single product can fill within the group - Per-product spend cap —
maxSpendPerConfigCentscaps the total dollars allocated to any single product within the group - Fulfillment —
recipientAddressId,paymentTokenId,paymentRailpropagate down to every fill in the group - Variance — default per-product bound around fair value (overridable per strategy)
Grouped Strategy
A child of the group that defines:
filterCriteria— which products to target (fair-value range, confidence floor, category filters, text query). Re-evaluated every time the strategy runspricingMode— how the strategy prices:VARIANCE(off fair value) orFLAT(a fixed price). See Pricing Modesvariance— per-strategy override of the group's pricing bounds. NULL inherits from the group.VARIANCEmode onlyflatBidCents— fixed bid per product. Required forFLATmode, forbidden otherwisetargetQuantity— how many units this strategy aims to fillminQuantityPerCheckout— minimum units a seller must fill in a single checkout for this strategy to bid. NULL means no floor. Works in bothVARIANCEandFLATmodeminBidCents/maxBidCents— hard floor and ceiling on the computed bid per product.VARIANCEmode only
Each strategy continuously matches products in its filter and bids on them — either at a discount to fair value (VARIANCE pricing) or at a fixed flat price (FLAT pricing). The group's budget and unit caps apply across every strategy underneath it.
Multiple pricing models per group. Each strategy stores its own fvModelConfigId, so a single group can hold strategies pricing against different fair-value models (e.g. CardHedge and TCGPlayer against the same PSA 10 grade). All strategies share the group's budget and unit caps, but each prices independently against its own model.
Group Types
| Type | Behavior |
|---|---|
| STANDARD | Group-driven. Variance lives on the group; strategies inherit unless they override |
More group types coming soon.
Fill Modes
fillMode controls how the allocator picks between competing strategies when their filters overlap:
| Mode | Behavior |
|---|---|
| DEFAULT | Highest bidAmountCents × qty wins |
More fill modes coming soon.
Pricing Modes
pricingMode controls whether a strategy prices against fair value or bids a fixed amount.
| Mode | Behavior |
|---|---|
| VARIANCE | Bid is anchored to fair value: fairValue − belowFv, clamped by minBidCents / maxBidCents and capped at fairValue + aboveFv. This is the default |
| FLAT | Bid is a fixed flatBidCents, independent of fair value |
The mode is set at two levels:
- Group —
data.pricingMode(aGroupPricingMode):VARIANCE(default),FLAT, orMIXED - Strategy —
strategyConfig.pricingMode(aStrategyPricingMode):VARIANCE(default) orFLAT
A VARIANCE or FLAT group forces every child strategy to that mode. A MIXED group lets each strategy choose its own. Adding or updating a strategy whose mode conflicts with its group returns a PRICING_MODE_MISMATCH error.
In a MIXED group, flat and variance strategies compete on equal footing — the highest bidAmountCents × qty still wins.
FLAT strategies set flatBidCents (≥ 1) and must omit every fair-value field: variance, minBidCents, maxBidCents, and the filterCriteria fields fvMinCents, fvMaxCents, fvConfidenceMin, and fvDriftRules. Targeting fields (keyCriteria, facets, query) still apply — a flat strategy bids flatBidCents on every product its filter matches. Sending any forbidden field is rejected.
Creating a Strategy Group
Mutation
mutation CreateBiddingStrategyGroup($input: CreateBiddingStrategyGroupInput!) {
createBiddingStrategyGroup(input: $input) {
group {
id
name
groupType
isActive
isDraft
maxGroupSpendCents
maxUnitQuantity
maxFillsPerConfig
createdAt
}
error {
message
code
}
}
}
Input Fields
| Field | Type | Required | Description |
|---|---|---|---|
| assetTypeId | ID | Yes | Asset type this group targets — look up valid IDs via Asset Types → List Asset Types |
| name | String | Yes | Human-readable name (min length 1) |
| groupType | BiddingStrategyGroupType | No | STANDARD (default) |
| description | String | No | Free-form description |
| data | StandardGroupData | No | Variance defaults and fill mode (see StandardGroupData) |
| externalReferenceId | String | No | Your reference ID for tracking |
| recipientAddressId | ID | No | Saved address for shipping fills from this group (see Address Management) |
| paymentTokenId | ID | No | Saved payment method to charge when strategies in this group win |
| paymentRail | PaymentRail | No | CARD, ACH, WIRE, TRADEPOST_BALANCE |
| maxGroupSpendCents | Int | No | Aggregate spend cap across all child strategies (≥ 1) |
| maxUnitQuantity | Int | No | Aggregate unit cap across all child strategies (≥ 1) |
| maxFillsPerConfig | Int | No | Per-product fill cap within the group (≥ 1) |
| maxSpendPerConfigCents | Int | No | Per-product spend cap within the group in cents (≥ 1). Prevents over-allocating to any single product regardless of fill count |
New groups start as isDraft: true, isActive: false. Call setBiddingStrategyGroupStatus with ACTIVATE once child strategies have been added.
StandardGroupData
Per-group pricing defaults applied to any child strategy that doesn't override them.
{
"variance": {
"aboveFv": { "unit": "PCT", "value": 0.05 },
"belowFv": { "unit": "PCT", "value": 0.15 }
},
"fillMode": "DEFAULT",
"pricingMode": "VARIANCE"
}
| Field | Type | Description |
|---|---|---|
| variance.aboveFv | VarianceBound | Caps the bid at fair value + this bound. Applied last, so it can lower a bid below minBidCents |
| variance.belowFv | VarianceBound | Lower bound around fair value (drives the bid discount) |
| fillMode | GroupFillMode | DEFAULT (see Fill Modes) |
| pricingMode | GroupPricingMode | VARIANCE (default), FLAT, or MIXED (see Pricing Modes) |
VarianceBound is either:
{ "unit": "PCT", "value": <0..1> }— decimal fraction of fair value (0.15= 15%){ "unit": "CENTS", "value": <int> }— absolute cents
Querying Groups
Get Single Group
query GetBiddingStrategyGroup($input: GetBiddingStrategyGroupInput!) {
getBiddingStrategyGroup(input: $input) {
group {
id
name
groupType
isActive
isDraft
maxGroupSpendCents
currentGroupSpendCents
pendingGroupSpendCents
maxUnitQuantity
currentUnitQuantity
pendingUnitQuantity
configFillCounts
biddingStrategies {
id
name
isActive
}
}
error {
message
code
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
| groupId | ID | Yes | Group to fetch |
| includeStrategies | Boolean | No | Hydrate child strategies (default false) |
List Groups
query ListBiddingStrategyGroups($input: ListBiddingStrategyGroupsInput!) {
listBiddingStrategyGroups(input: $input) {
groups {
id
name
groupType
isActive
}
pagination {
totalCount
limit
offset
}
error {
message
code
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
| assetTypeId | ID | No | Filter by asset type |
| isActive | Boolean | No | Filter by active state |
| includeStrategies | Boolean | No | Hydrate child strategies (default false) |
| pagination | SimplePaginationInput | No | Limit and offset (default limit=20, max 100) |
Updating a Group
mutation UpdateBiddingStrategyGroup($input: UpdateBiddingStrategyGroupInput!) {
updateBiddingStrategyGroup(input: $input) {
group {
id
name
maxGroupSpendCents
maxUnitQuantity
}
error {
message
code
}
}
}
All fields are optional — only the ones you pass are touched. Pricing changes propagate to all child strategies that inherit the group default. Strategies with their own variance override are unaffected.
| Field | Type | Description |
|---|---|---|
| groupId | ID! | Group to update |
| name | String | New name |
| description | String | New description |
| data | StandardGroupData | Replace variance defaults / fill mode |
| recipientAddressId | ID | New ship-to |
| paymentTokenId | ID | New payment method |
| paymentRail | PaymentRail | New payment rail |
| maxGroupSpendCents | Int | New aggregate spend cap |
| maxUnitQuantity | Int | New aggregate unit cap |
| maxFillsPerConfig | Int | New per-product fill cap |
| maxSpendPerConfigCents | Int | New per-product spend cap in cents |
Deleting a Group
Soft-deletes a group and deactivates all child strategies. The row is hard-deleted by a cleanup job after the retention window.
mutation DeleteBiddingStrategyGroup($input: DeleteBiddingStrategyGroupInput!) {
deleteBiddingStrategyGroup(input: $input) {
group {
id
deletedAt
}
error {
message
code
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
| groupId | ID | Yes | Group to delete |
Adding Strategies to a Group
Mutation
mutation AddStrategyToGroup($input: CreateGroupedStrategyInput!) {
addStrategyToGroup(input: $input) {
group {
id
biddingStrategies {
id
name
isActive
}
}
error {
message
code
}
}
}
Input Fields
| Field | Type | Required | Description |
|---|---|---|---|
| groupId | ID | Yes | Parent group |
| name | String | Yes | Strategy name (min length 1) |
| description | String | No | Free-form description |
| strategyConfig | GroupedStrategyConfig | Yes | Filter + pricing (see GroupedStrategyConfig) |
| maxStrategySpendCents | Int | No | Per-strategy spend cap (≥ 1) |
| maxUnitQuantity | Int | No | Per-strategy unit cap (≥ 1) |
New strategies are inactive by default — they don't bid until the group is activated (or setStrategyStatus with ACTIVATE is called on them).
GroupedStrategyConfig
Defines what a strategy targets and how it prices.
{
"pricingMode": "VARIANCE",
"filterCriteria": {
"keyCriteria": [
{ "fvKeyIds": ["<key-id>"], "requiredKeyIds": [] }
],
"fvModelConfigId": "<model-config-id>",
"fvMinCents": 5000,
"fvMaxCents": 50000,
"fvConfidenceMin": 0.7,
"facets": {
"include": { "asset_data.subcategory": ["POKEMON_CARDS"] },
"exclude": { "config_data.rarity": ["Common", "Uncommon"] }
},
"excludedAssetConfigIds": [],
"fvDriftRules": [],
"query": null
},
"variance": {
"belowFv": { "unit": "PCT", "value": 0.20 }
},
"targetQuantity": 100,
"minQuantityPerCheckout": 10,
"minBidCents": 1000,
"maxBidCents": 100000
}
| Field | Type | Description |
|---|---|---|
| pricingMode | StrategyPricingMode | VARIANCE (default) or FLAT (see Pricing Modes) |
| filterCriteria.keyCriteria | [KeyCriterion] | Grade targeting groups — OR across groups, AND within each group. See Grade and auto grade targeting. Required to fill — the matcher skips strategies with no matching criterion |
| filterCriteria.fvModelConfigId | String | Fair-value model to price against — look up valid IDs via Fair Value → Model Configs |
| filterCriteria.fvMinCents | Int | Inclusive lower bound on fair value. VARIANCE mode only |
| filterCriteria.fvMaxCents | Int | Inclusive upper bound on fair value. VARIANCE mode only |
| filterCriteria.fvConfidenceMin | Float | Confidence floor, 0–1. VARIANCE mode only |
| filterCriteria.facets | FacetFilter | Include/exclude product attributes — discover valid fields and values via Catalog → Filter Builder |
| filterCriteria.excludedAssetConfigIds | [UUID] | Product config IDs to drop from matching even if they pass every other filter — see Excluding specific products |
| filterCriteria.facetRanges | JSON | Numeric range bounds per numeric facet field (e.g. release year) — see Numeric range filters |
| filterCriteria.fvDriftRules | [FvDriftRule] | Block bidding during sharp fair-value swings — see Fair-value drift guards. VARIANCE mode only |
| filterCriteria.query | String | Optional text query |
| variance | Variance | Per-strategy pricing bound. NULL inherits the group default. VARIANCE mode only |
| flatBidCents | Int | Fixed bid per product (≥ 1). Required for FLAT mode, forbidden for VARIANCE |
| targetQuantity | Int | Fill target for this strategy (≥ 1) |
| minQuantityPerCheckout | Int | Minimum units a seller must fill in a single checkout for this strategy to bid (≥ 1, must be ≤ targetQuantity). Omit for no floor. Works in both pricing modes |
| minBidCents | Int | Hard floor on computed bid per product. VARIANCE mode only |
| maxBidCents | Int | Hard ceiling on computed bid per product (must be ≥ minBidCents). VARIANCE mode only |
KeyCriterion
| Field | Type | Description |
|---|---|---|
fvKeyIds | [String!]! | Keys to price against. The bid uses the highest fair value across these keys |
requiredKeyIds | [String!]! | Keys the item must also carry. If any are absent the criterion fails |
Grade and auto grade targeting
keyCriteria is the primary way to specify which graded variants a strategy will bid on. Each element is a KeyCriterion:
{ "fvKeyIds": ["<grade-key-id>"], "requiredKeyIds": [] }
The matcher evaluates criteria with OR across groups, AND within each group:
- An item satisfies the strategy if it passes any single criterion in full.
- Within a criterion, the item must carry every key in both
fvKeyIdsandrequiredKeyIds.
Bidding on multiple grades — one criterion per grade, no AND constraint:
{
"keyCriteria": [
{ "fvKeyIds": ["<PSA 10 keyId>"], "requiredKeyIds": [] },
{ "fvKeyIds": ["<PSA 9 keyId>"], "requiredKeyIds": [] }
]
}
Requiring an auto grade — use requiredKeyIds to add the AND gate. An item with PSA 9 but no matching auto grade is rejected:
{
"keyCriteria": [
{
"fvKeyIds": ["<PSA 9 keyId>"],
"requiredKeyIds": ["<PSA Auto 9 keyId>"]
}
]
}
Auto-only — bid on any item carrying a specific auto grade, regardless of card grade:
{
"keyCriteria": [
{ "fvKeyIds": ["<PSA Auto 9 keyId>"], "requiredKeyIds": [] }
]
}
To discover CARD_AUTO_GRADE key IDs, call listKeyConfigurations for the asset type and filter for keyType: "CARD_AUTO_GRADE". Each auto grade key has a corresponding CARD_GRADE key in the same key configuration — see Catalog → Keys.
Excluding specific products
filterCriteria.excludedAssetConfigIds is a deny-list of product configuration IDs. Any product in the list is never matched by the strategy, even if it passes every other filter — an "everything in this filter except these" carve-out.
This differs from facets.exclude, which excludes products by attribute value (rarity, set, etc.). Use excludedAssetConfigIds to drop specific known products by ID. The list is per-strategy; omit it or pass [] for no exclusions.
{
"filterCriteria": {
"facets": { "include": { "asset_data.subcategory": ["POKEMON_CARDS"] } },
"excludedAssetConfigIds": [
"a1b2c3d4-0000-0000-0000-000000000001",
"a1b2c3d4-0000-0000-0000-000000000002"
]
}
}
Numeric range filters
filterCriteria.facetRanges narrows the strategy to products whose numeric facet value falls in a range — e.g. trading cards released 2015–2020. It's a map of facet field path → bound object, applied on top of facets.
{
"filterCriteria": {
"facets": { "include": { "asset_data.subcategory": ["POKEMON_CARDS"] } },
"facetRanges": {
"asset_data.release_year": { "greaterThanOrEqual": 2015, "lessThanOrEqual": 2020 }
}
}
}
Each bound object supports any combination of these (all optional, but set at least one):
| Field | Meaning |
|---|---|
greaterThan | strictly > |
greaterThanOrEqual | inclusive >= |
lessThan | strictly < |
lessThanOrEqual | inclusive <= |
equalTo | exact match (exclusive with the bounds above) |
Notes:
- Works on numeric facet fields (discover them via Catalog → Filter Builder).
asset_data.release_yearis a plain year (e.g.2018); date fields like sealedasset_data.release_datetake an epoch timestamp in seconds, not a calendar year. - A product with no value for the field won't match.
- Use
facetRangesfor "between X and Y" on numbers; usefacetsfor discrete string values.
Fair-value drift guards
filterCriteria.fvDriftRules protect a strategy from bidding into a sudden fair-value swing (for example, a manipulated or thin market). While a product's fair value has moved more than the allowed amount over a recent window, the strategy stops bidding on that product; it resumes once the move falls back within range.
Drift guards apply to VARIANCE strategies only — FLAT strategies don't reference fair value and reject fvDriftRules.
Each rule:
{ "direction": "UP", "maxDriftBps": 1500, "windowSeconds": 86400 }
| Field | Type | Description |
|---|---|---|
| direction | FvDriftDirection | UP (block on upward moves), DOWN (downward), or BOTH (either) |
| maxDriftBps | Int | Maximum allowed move in basis points (100 bps = 1%), 1–10000 |
| windowSeconds | Int | Lookback window in seconds, 1–2592000 (max 30 days) |
Rules:
- Up to 10 drift rules per strategy.
- Within the same
windowSecondsyou can't repeat adirection, andBOTHcan't be combined withUP/DOWN(useUP+DOWN, or justBOTH). - A rule only acts once there's enough recent price history to compare against — until then it doesn't block.
Block bidding if fair value jumps more than 15% in a day, or falls more than 25% in a week:
{
"filterCriteria": {
"keyCriteria": [{ "fvKeyIds": ["<key-id>"], "requiredKeyIds": [] }],
"fvDriftRules": [
{ "direction": "UP", "maxDriftBps": 1500, "windowSeconds": 86400 },
{ "direction": "DOWN", "maxDriftBps": 2500, "windowSeconds": 604800 }
]
}
}
Population filters
Targeting strategies by graded-card population — PSA / CGC pop counts, gem rates, and grade-level thresholds via filterCriteria.pop — is coming soon. Full documentation will follow once it's generally available.
Updating a Strategy
mutation UpdateGroupedStrategy($input: UpdateGroupedStrategyInput!) {
updateGroupedStrategy(input: $input) {
group {
id
biddingStrategies {
id
name
isActive
}
}
error {
message
code
}
}
}
All fields except groupId and strategyId are optional.
| Field | Type | Description |
|---|---|---|
| groupId | ID! | Parent group |
| strategyId | ID! | Strategy to update |
| name | String | New name |
| strategyConfig | GroupedStrategyConfig | Replace filter + pricing |
| maxStrategySpendCents | Int | New per-strategy spend cap |
| maxUnitQuantity | Int | New per-strategy unit cap |
Removing a Strategy
Detaches and deactivates a single strategy from a group.
mutation RemoveStrategyFromGroup($input: RemoveStrategyFromGroupInput!) {
removeStrategyFromGroup(input: $input) {
group {
id
biddingStrategies {
id
name
isActive
}
}
error {
message
code
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
| groupId | ID | Yes | Parent group |
| strategyId | ID | Yes | Strategy to remove |
Group Lifecycle
Drive group and strategy state through two mutations.
Set Group Status
mutation SetBiddingStrategyGroupStatus($input: SetBiddingStrategyGroupStatusInput!) {
setBiddingStrategyGroupStatus(input: $input) {
group {
id
isActive
isDraft
pausedAt
deletedAt
}
error {
message
code
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
| groupId | ID | Yes | Group to transition |
| action | String | Yes | ACTIVATE, PAUSE, RESUME, or DELETE |
Transitions
| Action | Allowed when | Effect |
|---|---|---|
| ACTIVATE | Group is draft, or paused and not draft | Activates every child strategy, sets isActive: true, isDraft: false, clears pausedAt. Requires at least one strategy attached |
| PAUSE | Group is active and not draft | Deactivates every child strategy, sets pausedAt to now |
| RESUME | Group is paused and not draft | Reactivates every child strategy, clears pausedAt |
| DELETE | Any state | Deactivates all children and soft-deletes the group (equivalent to deleteBiddingStrategyGroup) |
Set Strategy Status
mutation SetStrategyStatus($input: SetStrategyStatusInput!) {
setStrategyStatus(input: $input) {
group {
id
biddingStrategies {
id
isActive
}
}
error {
message
code
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
| groupId | ID | Yes | Parent group |
| strategyId | ID | Yes | Strategy to toggle |
| action | String | Yes | ACTIVATE or DEACTIVATE |
ACTIVATE clears the draft flag and turns on the strategy. If the parent group is also active, the strategy participates in fills immediately.
BiddingStrategyGroup Type
Returned by all create, update, query, and lifecycle operations.
| Field | Type | Description |
|---|---|---|
| id | ID! | Unique identifier |
| accountId | ID! | Account that owns this group |
| assetTypeId | ID! | Asset type this group targets |
| externalReferenceId | String | Your reference ID |
| recipientAddressId | ID | Saved ship-to inherited by all fills |
| paymentTokenId | ID | Saved payment method |
| paymentRail | PaymentRail | Payment rail (CARD, ACH, WIRE, TRADEPOST_BALANCE) |
| groupType | BiddingStrategyGroupType! | STANDARD |
| name | String! | Human-readable name |
| description | String | Free-form description |
| data | StandardGroupData | Variance defaults and fill mode |
| isActive | Boolean! | Whether the group is bidding |
| isDraft | Boolean! | True until first activation |
| isHidden | Boolean! | Archived from the Terminal view |
| maxGroupSpendCents | Int | Aggregate spend cap |
| currentGroupSpendCents | Int | Spend committed by completed fills |
| pendingGroupSpendCents | Int | Spend reserved by in-flight fills |
| maxUnitQuantity | Int | Aggregate unit cap |
| currentUnitQuantity | Int | Units filled |
| pendingUnitQuantity | Int | Units reserved by in-flight fills |
| maxFillsPerConfig | Int | Per-product fill cap |
| configFillCounts | JSON | { "<productId>": fillCount } — running fill tally per product |
| maxSpendPerConfigCents | Int | Per-product spend cap in cents |
| configSpendCounts | JSON | { "<productId>": spentCents } — running spend tally per product |
| createdAt | DateTime! | Created timestamp |
| updatedAt | DateTime! | Last modified timestamp |
| expiresAt | DateTime | Group becomes inactive after this time |
| pausedAt | DateTime | When the group was paused (null if not paused) |
| deletedAt | DateTime | When the group was soft-deleted (null if not deleted) |
| biddingStrategies | [BiddingStrategy!] | Child strategies (hydrated when includeStrategies: true) |
Quickstart
This walkthrough builds a real strategy end to end. Each step is one GraphQL call you can copy/paste — swap in your own API key and you'll end up with an activated strategy bidding on PSA 10 trading cards.
Step 1 — Find your asset type ID
Most TPX endpoints reference asset types by UUID. Look it up by the human-readable identifier.
query { assetTypes(input: { type: TRADING_CARD }) { assetTypes { id type } } }
Returns:
{ "assetTypes": { "assetTypes": [{ "id": "5e78b0f7-e476-48fe-bb8d-31a7f79523ab", "type": "TRADING_CARD" }] } }
Save the id as your assetTypeId. See Asset Types.
Step 2 — Pick a pricing model
query L($i: ListFairValueModelConfigsInput!) {
listFairValueModelConfigs(input: $i) {
modelConfigs { id name version description }
}
}
{ "i": { "assetTypeId": "5e78b0f7-e476-48fe-bb8d-31a7f79523ab" } }
Returns several configs. Pick one — e.g. CardHedge Trading Card Market — and save its id as your fvModelConfigId. See Fair Value → Model Configs.
Step 3 — Pick the grades you'll bid on
query K($i: ListKeyConfigurationsInput!) {
listKeyConfigurations(input: $i) {
keyConfigurations { keyData { keys { keyId keyType value displayName ancestors } } }
}
}
{ "i": { "assetTypeId": "5e78b0f7-e476-48fe-bb8d-31a7f79523ab" } }
Filter the response for the variants you want (e.g. keyType: "CARD_GRADE", value: "PSA_10") and collect those keyIds. If you also want to require a specific auto grade, find the matching CARD_AUTO_GRADE keys in the same response.
You'll place these IDs into keyCriteria in Step 6. See Catalog → Keys.
Step 4 — (Optional) Explore product filters
If you want to narrow to specific brands, sets, or rarities, look up what facet fields exist:
query F($i: FilterBuilderInput!) {
getFilterBuilderData(input: $i) {
availableFacetFields
totalProducts
}
}
{ "i": { "assetTypeId": "5e78b0f7-e476-48fe-bb8d-31a7f79523ab", "skipFacets": true } }
Use the field names (e.g. asset_data.brand) as keys in facets.include / facets.exclude. See Catalog → Filter Builder.
Step 5 — Create the group
mutation C($i: CreateBiddingStrategyGroupInput!) {
createBiddingStrategyGroup(input: $i) {
group { id name isDraft }
error { message code }
}
}
{
"i": {
"assetTypeId": "5e78b0f7-e476-48fe-bb8d-31a7f79523ab",
"name": "PSA 10 Strategy",
"maxGroupSpendCents": 10000000,
"data": {
"variance": { "belowFv": { "unit": "PCT", "value": 0.15 } },
"fillMode": "DEFAULT"
}
}
}
Save the returned group.id as your groupId. The group starts in draft mode — you'll activate it in step 7.
Step 6 — Add a strategy
mutation A($i: AddStrategyToGroupInput!) {
addStrategyToGroup(input: $i) {
group { biddingStrategies { id name } }
error { message code }
}
}
{
"i": {
"groupId": "<groupId from step 5>",
"name": "PSA 10 — CardHedge",
"strategyConfig": {
"filterCriteria": {
"fvModelConfigId": "<fvModelConfigId from step 2>",
"keyCriteria": [
{ "fvKeyIds": ["<PSA 10 keyId from step 3>"], "requiredKeyIds": [] }
],
"fvMinCents": 10000,
"fvMaxCents": 100000,
"fvConfidenceMin": 0.7,
"facets": { "include": { "asset_data.brand": ["Pokemon"] } }
},
"variance": { "belowFv": { "unit": "PCT", "value": 0.20 } },
"targetQuantity": 50
}
}
}
This strategy targets PSA 10 Pokémon cards priced by CardHedge between $100–$1,000, bidding 20% below fair value, capped at 50 fills.
Step 7 — Activate
mutation S($i: SetBiddingStrategyGroupStatusInput!) {
setBiddingStrategyGroupStatus(input: $i) {
group { isActive isDraft }
error { message code }
}
}
{ "i": { "groupId": "<groupId>", "action": "ACTIVATE" } }
The group and its strategies flip to isActive: true and start matching incoming offers in the background.
Step 8 — Read it back
query G($i: GetBiddingStrategyGroupInput!) {
getBiddingStrategyGroup(input: $i) {
group {
name
isActive
biddingStrategies {
name
isActive
groupedStrategyConfig {
filterCriteria { fvModelConfigId keyCriteria { fvKeyIds requiredKeyIds } fvMinCents fvMaxCents }
variance { belowFv { unit value } }
targetQuantity
}
}
}
}
}
{ "i": { "groupId": "<groupId>", "includeStrategies": true } }
You should see your strategy with the full filter criteria you sent. The strategy is now live — incoming offers matching your filter will receive bids automatically until the group's budget or unit cap is hit.
Where to go from here
- More strategies in the same group: call
addStrategyToGroupagain with a different filter — even a differentfvModelConfigId. The group's caps apply across all of them. - Tune live:
updateGroupedStrategychanges filter or variance on an existing strategy without recreating it. - Pause / resume / tear down: Group Lifecycle.
Support
- Email: support@tradepost.co
- Include: Group ID, strategy ID, example
strategyConfig, error messages
← Conditional Bidding | Saved Addresses →
© 2026 Tradepost Markets Inc. All rights reserved.