type Attack { """ Energy types required, one entry per Energy. """ cost: [String!]! """ Printed damage, e.g. "90", "30+", "20×". """ damage: String effect: String name: String! } """ Red flags that a card is fake, from photos. Never says a card is genuine. """ type AuthenticityCheck { """ The real card the photo was compared with. """ card: Card """ What was compared and matched the real card. """ checked: [String!]! disclaimer: String! """ MATCH, AMBIGUOUS or NO_MATCH (see identifyCard). """ identificationStatus: String! model: String! notChecked: [String!]! """ Weak observations the lighting or the photo could explain (e.g. a colour shift); never decide the verdict. """ notes: [String!]! """ Checks a photo can't do, for the holder of the card. """ physicalChecks: [String!]! """ Strongest first. Only strong and medium ones. """ redFlags: [RedFlag!]! timingsMs: JSON! verdict: AuthenticityVerdict! } """ Never 'genuine': a photo can't prove a card is real. """ enum AuthenticityVerdict { """ Not recognised, nothing to compare with, too little could be read, or a single medium red flag (not enough on its own). """ CANT_TELL """ Strong evidence the card is counterfeit (see redFlags). """ LIKELY_FAKE """ Everything we could check matches the real card. Not proof that it's real. """ NO_RED_FLAGS } """ Every card found in one photo of several (a spread or a binder page), identified one by one. """ type BatchIdentification { cards: [BatchIdentificationCard!]! """ How many cards were found. """ detected: Int! """ outlines (cards found by their edges) or grid (the photo split evenly). """ foundBy: String! hints: [String!]! } """ One card in the photo: its identification, or why it has none. """ type BatchIdentificationCard { box: PhotoBox! column: Int! error: String """ Null when error says why (photo quota, too small). """ identification: Identification """ Position in reading order, from 0. """ index: Int! row: Int! } """ A card as printed in one set. Its printings are the collectible variants (normal, reverse holo, stamped…). """ type Card implements Node { abilities: [CardAbility!]! attacks: [Attack!]! """ Our card id: TCGdex's id (e.g. swsh3-136), prefixed with asia: for Asian cards. """ code: String! """ Rules text for Trainer and Energy cards. """ effect: String """ For Japanese and other Asian cards: the English name, from TCGplayer's English listing, or (englishNameSource DERIVED) from the Pokémon's name plus the card's suffix. Null when unknown. """ englishName: String """ tcgplayer or derived. """ englishNameSource: String evolvesFrom: String """ IDs in other systems, e.g. pokemontcg.io (sv3-125). """ externalIds: [ExternalId!]! flavorText: String hp: Int """ ID of the object. """ id: ID! illustrator: String """ Card scan. """ image: Image legalities: Legalities! localizedNames: [LocalizedName!]! name( """ Defaults to the card's primary language. """ locale: String ): String! """ Collector number as printed. """ number: String! printings: [Printing!]! """ TCGplayer's photo of the card, hosted by TCGplayer (linked, not copied). Mainly useful for Asian cards with no scan in `image`; show its credit. """ productImage: ExternalImage rarity: String regulationMark: String resistances: [TypeModifier!]! retreatCost: Int set: Set! species: [CardSpeciesLink!]! """ Basic, Stage1, Stage2, VMAX… """ stage: String """ e.g. EX, V, VMAX, Item, Supporter, Special. """ subtypes: [String!]! supertype: Supertype! types: [String!]! weaknesses: [TypeModifier!]! } type CardAbility { effect: String name: String! """ e.g. Ability, Poké-Power, Poké-Body. """ type: String } """ The connection type for Card. """ type CardConnection { """ A list of edges. """ edges: [CardEdge] """ A list of nodes. """ nodes: [Card] """ Information to aid in pagination. """ pageInfo: PageInfo! } """ An edge in a connection. """ type CardEdge { """ A cursor for use in pagination. """ cursor: String! """ The item at the end of the edge. """ node: Card } """ All given fields must match. """ input CardFilter { """ false = physical cards only; true = TCG Pocket only. """ digital: Boolean illustrator: String """ Case-insensitive substring of the card name. """ name: String """ Cards featuring this Pokédex number. """ nationalDex: Int rarity: String region: Region regulationMark: String setCode: String standardLegal: Boolean supertype: Supertype """ Energy type, e.g. Fire. """ type: String } enum CardOrder { """ Alphabetical by card name. """ NAME """ Oldest sets first, then card number. """ RELEASE_DATE_ASC """ Newest sets first, then card number. """ RELEASE_DATE_DESC } """ What the vision model read on the card. Null means it couldn't read that clearly. """ type CardReading { copyrightYears: String firstEditionStamp: Boolean! foilPattern: String """ artwork (holo), whole_card (reverse holo), none, unknown. """ holoArea: String! isTradingCard: Boolean! language: String legibility: Float! name: String notes: String number: String otherStamps: [String!]! printedTotal: String regulationMark: String setCode: String """ Base Set era only. """ shadowless: Boolean slabCert: String slabGrade: String """ Set when the card is in a graded slab. """ slabGrader: String } """ A species on a card. Tag-team cards link several; cameo links are Pokémon that only appear in the artwork. """ type CardSpeciesLink { cameo: Boolean! """ Set when the card is a specific form, e.g. Alolan Vulpix or Mega Charizard X ex. """ form: Form species: Species! } type Centering { """ Measured border width per side in mm (null where not measurable). """ bordersMm: JSON! """ Null when there's no clear, even border to measure. """ leftRight: CenteringRatio topBottom: CenteringRatio } """ The best grade a grader's published centering limits allow for the measured centering. """ type CenteringLimit { """ e.g. 9, Gem Mint 10. Null when the grader publishes no limit this low. """ grade: String grader: String! note: String value: Float } """ Border widths on one axis as percentages, e.g. 57 / 43 (left / right or top / bottom). """ type CenteringRatio { display: String! """ Left or top share. """ first: Float! """ Right or bottom share. """ second: Float! """ ± in percentage points. """ uncertainty: Float! } """ A condition estimate from photos: measured centering and whitening, visible defects, and the grade range they allow. """ type ConditionAssessment { back: ConditionSide """ What these photos can't show. """ cannotAssess: [String!]! centeringLimits: [CenteringLimit!]! """ high, medium or low: how narrow the range is. """ confidence: String! defects: [ConditionDefect!]! disclaimer: String! front: ConditionSide! gradeRange: GradeRange! """ What holds the grade down, worst first. """ limitingFactors: [String!]! model: String! timingsMs: JSON! } """ Damage the vision model saw (only those at least 50% likely). """ type ConditionDefect { confidence: Float! """ crease, dent, indentation, scratch, print_line, stain, writing, whitening, edge_chip, corner_wear. """ kind: String! location: String! """ minor, moderate or major. """ severity: String! side: String! } """ What was measured on one side of the card. """ type ConditionSide { """ The card's width in the photo. """ cardShortEdgePx: Int! centering: Centering! glareFraction: Float! sharpness: Float! wear: [Wear!]! } enum ContentsStatus { """ Read automatically from the retailer description; quantities are reliable, promo identity usually missing. """ PARSED """ We know the product but not its contents. """ UNPARSED """ Checked by hand against the product listing. """ VERIFIED } """ A currency to show prices in. Cardmarket prices are euros; others are converted at the European Central Bank's reference rate for the price's date. """ enum Currency { AUD CAD EUR GBP JPY USD } """ Anything search or resolveId can return. """ union Entity = Card | Printing | SealedProduct | Set | Species """ What opening this is worth on average at today's Cardmarket prices. Read `caveats`: EV ignores bulk selling costs and assumes cards of a rarity are equally likely. """ type ExpectedValue { asOf: ISO8601Date caveats: [String!]! currency: String! """ When converted: the date of that rate. """ fxDate: ISO8601Date """ When converted: units of `currency` per euro used (European Central Bank reference rate). """ fxRate: Float lines: [ExpectedValueLine!]! """ Share of the set's cards (in the lines) that have a price, 0–1. """ priceCoverage: Float samplePacks: Int sources: [String!]! """ Null when it can't be computed; `caveats` says why. """ total: Float """ pack or product. """ unit: String! } type ExpectedValueLine { cardCount: Int """ quantity × probability × unitValue. Null when nothing in the line has a price. """ contribution: Float """ A rarity, or for sealed products a pack/card/product. """ label: String! """ How many of cardCount have a price today. """ pricedCount: Int probability: Float! quantity: Int! slot: String! """ Mean price of the cards in this line (or value of one pack/product). """ unitValue: Float } """ This record's identifier in another system. Pass it to resolveId to come back here. """ type ExternalId { """ tcgdex, pokemontcg.io, tcgplayer or cardmarket. """ source: String! value: String! } """ A product photo hosted by a marketplace. We link to it and don't host or license it: show it with its credit and a link to pageUrl, or not at all. """ type ExternalImage { """ Show this next to the image. """ credit: String! """ The marketplace's product page. """ pageUrl: String! """ Who hosts it, e.g. tcgplayer. """ source: String! """ About 200 px wide. """ thumbnailUrl: String! """ Full-size image (about 1000 px). """ url: String! } """ A battle form of a species with its own types and stats, e.g. vulpix-alola. """ type Form { abilities: [String!]! """ Official artwork. Currently not served (url is null). """ artwork: Image baseStats: [Stat!]! """ Decimetres. """ height: Int isDefault: Boolean! kind: FormKind! """ PokéAPI identifier, e.g. vulpix-alola, charizard-mega-x. """ name: String! species: Species! types: [String!]! """ Hectograms. """ weight: Int } enum FormKind { DEFAULT """ Gigantamax form. """ GMAX MEGA OTHER """ Alolan, Galarian, Hisuian or Paldean form. """ REGIONAL } """ Best and worst grade the photos allow, on the common 1–10 card grading scale. """ type GradeRange { high: Float! low: Float! scale: String! } """ An ISO 8601-encoded date """ scalar ISO8601Date @specifiedBy(url: "https://tools.ietf.org/html/rfc3339") """ An ISO 8601-encoded datetime """ scalar ISO8601DateTime @specifiedBy(url: "https://tools.ietf.org/html/rfc3339") """ The result of identifying a card from a photo. """ type Identification { """ Ranked alternatives with the evidence for each. """ candidates: [IdentificationCandidate!]! """ The best match (null for NO_MATCH). """ card: Card confidence: Float """ What would settle an ambiguous result (e.g. tilt to show the holo). """ hints: [String!]! """ Vision model that read the card. """ model: String! """ The exact printing, when the visible cues leave only one. """ printing: Printing """ Printings of the card still consistent with the photo. """ printings: [Printing!]! quality: PhotoQuality! reading: CardReading! """ When the card is in a graded slab: where to verify its cert. """ slab: SlabVerification status: IdentificationStatus! timingsMs: JSON! } type IdentificationCandidate { card: Card! """ Cosine similarity to the card's reference scan; null if it wasn't among the nearest. """ imageSimilarity: Float reasons: [String!]! """ 0–1, combining what was read with image similarity. """ score: Float! """ How well the printed text (number, set size, set code, name, language) matches. """ textScore: Float! } enum IdentificationStatus { """ Several cards are plausible; see `candidates` and `hints`. """ AMBIGUOUS """ One card stands out. `printing` is set when the visible cues narrow it to one printing. """ MATCH """ No card in the catalog fits what was read. """ NO_MATCH } type Image { """ large (card scan), logo, symbol or artwork. """ kind: String! """ Where the image originally came from. """ source: String! """ Null when this image is not currently served. """ url: String } type ImportError { message: String! row: Int! } type ImportMapping { """ order_id, sold_on, title, sku, set_name, number, quantity, item_price, shipping_charged, shipping_cost, fees, buyer or event. """ field: String! headers: [String!]! } input ImportMappingInput { """ One of order_id, sold_on, title, sku, set_name, number, quantity, item_price, shipping_charged, shipping_cost, fees, buyer, event. """ field: String! """ The column(s) holding it; several fee columns are added up. """ headers: [String!]! } """ Represents untyped JSON """ scalar JSON """ Tournament format legality. """ type Legalities { expanded: Boolean standard: Boolean } type LocalizedName { """ Language code, e.g. en, fr, ja, zh-tw. """ locale: String! name: String! } """ A price from a provider you queried with your own key. Quotes cover the whole TCGplayer product, so check `printing`. """ type MarketQuote { asOf: ISO8601DateTime """ Raw condition, e.g. Near Mint. Null for graded quotes. """ condition: String currency: String! grade: String """ PSA, BGS, CGC or SGC for graded sales. """ grader: String price: Float """ Provider's printing label, e.g. Normal, Reverse Holofoil, Holofoil. """ printing: String provider: PriceProvider! """ Number of sales behind a graded price. """ salesCount: Int } """ A link to look up live prices yourself. We do not fetch or store these marketplaces' prices. """ type MarketplaceLink { """ True when the link goes to this exact product; false when it is a search. """ exact: Boolean! """ tcgplayer, cardmarket, ebay_sold or pricecharting. """ marketplace: String! url: String! } """ Manage price alerts and the webhook endpoints they post to, and your Pullbook seller ledger. """ type Mutation { """ Spread one bill (a grading submission, say) evenly over items, to the cent. """ addExtraCost(amount: Float!, itemIds: [ID!]!, note: String): [PullbookItem!]! """ Add what came out of a purchase: cards by code, and a count of bulk cards. fromItemId puts them inside one of the purchase's sealed items (opening one unit of it). The cost is re-split. """ addPulls(bulk: Int = 0, fromItemId: ID, pulls: [PullInput!] = [], purchaseId: ID!): PullbookPurchase! """ A stream or card show to group sales by. """ createEvent(cost: Float = 0.0, heldOn: ISO8601Date!, kind: PullbookEventKind!, name: String!): PullbookEvent! """ Watch a printing's Cardmarket trend price. Name the card by code and, when it has several printings, the printing by key (see Card.printings). The printing must have a Cardmarket product. """ createPriceAlert(cardCode: String!, condition: PriceAlertCondition!, printingKey: String, threshold: Float!, webhookEndpointId: ID!): PriceAlert! """ A Stripe Checkout link for a paid plan. Open it in a browser to pay; your plan changes once Stripe confirms. """ createPullbookCheckout( """ month or year (founding is yearly only). """ interval: String! """ pro, dealer or founding. """ plan: String! ): String! """ Log something you bought. SEALED needs sealedProductId (a SealedProduct id); its units become an item you can open. Amounts are in your ledger's currency. """ createPurchase( """ You don't know what you paid (cards you've had for years): amounts are 0, items count toward holdings' value but not gain, and tax lots say so. """ costUnknown: Boolean = false kind: PullbookPurchaseKind! """ Defaults to the sealed product's name. """ name: String notes: String """ Required unless costUnknown. """ price: Float purchasedOn: ISO8601Date! quantity: Int = 1 sealedProductId: ID shipping: Float = 0.0 source: String tax: Float = 0.0 ): PullbookPurchase! """ Record a sale. Fees come from the channel's schedule unless you pass fees. Counts toward your plan's monthly sales. """ createSale(buyer: String, channel: PullbookChannel!, eventId: ID, externalOrderId: String, fees: Float, lines: [SaleLineInput!]!, notes: String, shippingCharged: Float = 0.0, shippingCost: Float = 0.0, soldOn: ISO8601Date!): PullbookSale! """ Register an https URL to receive events. Returns the signing secret, shown only this once. """ createWebhookEndpoint(url: String!): WebhookEndpointWithSecret! """ Delete a stream or show (its sales are kept). Returns its id. """ deleteEvent(id: ID!): ID! """ Remove an unsold item. Returns its id. """ deleteItem(id: ID!): ID! """ Stop an alert. Returns its id. """ deletePriceAlert(id: ID!): ID! """ Delete a purchase and its items (not once something from it has sold). Returns its id. """ deletePurchase(id: ID!): ID! """ Delete a sale; its items go back in stock. Returns its id. """ deleteSale(id: ID!): ID! """ Delete an endpoint and the alerts that post to it. Returns its id. """ deleteWebhookEndpoint(id: ID!): ID! """ Map the columns of an import that is NEEDS_MAPPING, and run it. """ finishImport(id: ID!, mapping: [ImportMappingInput!]!): PullbookImport! """ Import a sales export (CSV text, up to 2 MB / 5,000 rows). Columns are found by name for Whatnot, eBay and TCGplayer exports, or by a mapping you pass (or saved from an earlier file with the same headers). Re-importing is safe. """ importSales(channel: PullbookChannel!, csv: String!, filename: String, mapping: [ImportMappingInput!]): PullbookImport! """ Open one unit of a sealed item. Returns the opened unit. """ openItem(id: ID!): PullbookItem! """ A Stripe link to change or cancel your paid plan. Open it in a browser. """ pullbookBillingPortal: String! """ Settle a sold line: itemId sells that inventory item; costBasis says it wasn't from your ledger (and what it cost); unmatch: true puts its item back and the line back in review. """ resolveSaleLine( """ Say which card a REVIEW line is (with itemId, then sell that copy). """ cardCode: String costBasis: Float id: ID! itemId: ID unmatch: Boolean ): PullbookSaleLine! """ Replace an endpoint's signing secret. The old one stops working immediately. """ rotateWebhookSecret(id: ID!): WebhookEndpointWithSecret! """ POST a signed ping event to an endpoint now (no retries) and return how it answered. """ sendTestWebhook(id: ID!): WebhookDelivery! updateEvent(cost: Float, heldOn: ISO8601Date, id: ID!, kind: PullbookEventKind, name: String): PullbookEvent! """ Set an item's value for splitting cost, its condition or grade, or what was spent on it alone. """ updateItem( """ true: go back to the market price (same as valueOverride: null). """ clearValueOverride: Boolean condition: String extraCost: Float extraCostNote: String grade: String id: ID! """ Per unit, on the Cardmarket (€) scale. Pass null to use the market price. """ valueOverride: Float ): PullbookItem! """ Change your ledger's currency (only before you've logged purchases) or the bulk card weight, or note which paid plan you'd like (PRO, DEALER or FOUNDING). To buy one, use createPullbookCheckout. """ updatePullbookSettings(bulkWeight: Float, currency: String, upgradeInterest: String): Pullbook! """ Edit a purchase. Changing what it cost re-splits the cost over unsold items. """ updatePurchase( costUnknown: Boolean id: ID! name: String notes: String """ Ignored while the purchase is costUnknown; send costUnknown: false with it. """ price: Float purchasedOn: ISO8601Date shipping: Float source: String tax: Float ): PullbookPurchase! } """ An object with an ID. """ interface Node { """ ID of the object. """ id: ID! } type PackSlot { count: Int! """ common, uncommon, reverse or rare. """ slot: String! } """ Information about pagination in a connection. """ type PageInfo { """ When paginating forwards, the cursor to continue. """ endCursor: String """ When paginating forwards, are there more items? """ hasNextPage: Boolean! """ When paginating backwards, are there more items? """ hasPreviousPage: Boolean! """ When paginating backwards, the cursor to continue. """ startCursor: String } """ Where a card is in the photo, as fractions (0–1) of the photo's width and height from the top left. """ type PhotoBox { height: Float! width: Float! x: Float! y: Float! } type PhotoQuality { """ Whether the card's outline was found and straightened. """ cardFound: Boolean! """ Share of the card that is blown-out highlight. """ glareFraction: Float! """ Variance of the Laplacian; under ~100 is blurry. """ sharpness: Float! shortEdgePx: Int! } """ A daily price snapshot. Cardmarket prices one product per card; reverse-holo printings report its holo columns. """ type Price { asOf: ISO8601Date! """ Show this wherever the price is displayed. """ attribution: String! avg: Float avg1: Float avg30: Float avg7: Float currency: String! """ When converted: the date of that rate. """ fxDate: ISO8601Date """ When converted: units of `currency` per euro used (European Central Bank reference rate). """ fxRate: Float low: Float source: PriceSource! trend: Float } """ Watches one printing's Cardmarket trend price (EUR) and POSTs to a webhook endpoint when the condition is met. Checked once a day after Cardmarket's daily price guide is imported. """ type PriceAlert { card: Card! condition: PriceAlertCondition! createdAt: ISO8601DateTime! id: ID! lastTriggeredOn: ISO8601Date printing: Printing! """ EUR for TREND_ABOVE / TREND_BELOW; percent for CHANGE_ABOVE_PERCENT. """ threshold: Float! webhookEndpoint: WebhookEndpoint! } enum PriceAlertCondition { """ Fires each day the trend price moves up or down by at least the threshold, in percent. """ CHANGE_ABOVE_PERCENT """ Fires the day the Cardmarket trend price rises to the threshold (EUR) or above. """ TREND_ABOVE """ Fires the day the Cardmarket trend price falls to the threshold (EUR) or below. """ TREND_BELOW } """ Third-party price APIs you can query with your own key, sent as an X-Provider-Key- header (e.g. X-Provider-Key-Justtcg). We never store the key. """ enum PriceProvider { """ JustTCG: raw prices by condition and printing (USD). """ JUSTTCG """ PokemonPriceTracker: TCGplayer market price per printing plus graded eBay sales (USD). """ POKEMONPRICETRACKER } enum PriceSource { """ Cardmarket (EU) daily price guide, in EUR. """ CARDMARKET } """ One collectible variant of a card: the unit marketplaces sell and price. """ type Printing implements Node { card: Card! cardmarketProductId: Int """ normal, holo, reverse, firstEdition… """ finish: String! """ Foil pattern, e.g. cosmos. """ foil: String """ ID of the object. """ id: ID! """ Stable variant id within the card. """ key: String! """ Live USD prices from a provider you have a key for (see PriceProvider). Results are cached for 6 hours per key. """ marketPrices(provider: PriceProvider!): [MarketQuote!]! """ Where to check live prices yourself: TCGplayer, Cardmarket, eBay sold listings, PriceCharting. """ marketplaceLinks: [MarketplaceLink!]! """ Latest daily price from Cardmarket, in euros unless you ask for another currency (converted at the ECB rate for its date). For live US marketplace prices, follow marketplaceLinks. """ price(currency: Currency = EUR, source: PriceSource = CARDMARKET): Price priceHistory( """ Each day converted at that day's rate. """ currency: Currency = EUR from: ISO8601Date source: PriceSource = CARDMARKET to: ISO8601Date ): [Price!]! size: String stamps: [String!]! """ Print run or variation: unlimited, shadowless, 1999-2000-copyright, or a known misprint (e.g. missing-expansion-symbol). """ subtype: String tcgplayerProductId: Int } """ A card that came out of a purchase. """ input PullInput { cardCode: String! """ Which printing, when the card has several (see Card.printings). """ printingKey: String quantity: Int = 1 } """ Per-pack odds of pulling a card of this rarity, from a published opening study. """ type PullRate { """ Published confidence interval, e.g. ±0.36%. """ ci: String observedOn: ISO8601Date """ As published, e.g. "1 in 81". """ odds: String """ Set for reverse-holo patterns (pokeball, masterball): odds of that pattern rather than a rarity. """ pattern: String """ Chance per pack, 0–1. """ probability: Float! """ Matches Card.rarity. """ rarity: String! """ Packs opened in the study (published as a floor, e.g. "more than 3,500"). """ samplePacks: Int """ rare, reverse_1 or reverse_2 (the two reverse-holo slots, either of which can upgrade). """ slot: String! source: String! sourceUrl: String! } """ Your Pullbook ledger: what you bought, what came out of it, and what it cost you. """ type Pullbook { """ What one bulk card weighs when cost is split, on the Cardmarket (€) scale. """ bulkWeight: Float! """ Every amount in the ledger is in this currency. """ currency: String! """ Streams and shows, newest first. """ events: [PullbookEvent!]! """ What you hold, what it cost and what it's worth at market prices. """ holdings: PullbookHoldings! """ One upload, to check on a running import. """ import(id: ID!): PullbookImport """ Sales exports you've uploaded, newest first. """ imports: [PullbookImport!]! """ Items not sold or opened, most expensive first. """ inventory: [PullbookItem!]! plan: String! purchase(id: ID!): PullbookPurchase purchases(kind: PullbookPurchaseKind): [PullbookPurchase!]! """ What you made, grouped; only settled sales count. """ report( groupBy: PullbookReportGroup! """ Sales in this calendar year; all time when left out. """ year: Int ): PullbookReport! """ Sold lines waiting to be matched to your inventory. """ reviewQueue: [PullbookSaleLine!]! sale(id: ID!): PullbookSale """ Newest first. """ sales(channel: PullbookChannel, eventId: ID, from: ISO8601Date, needsReview: Boolean, to: ISO8601Date): [PullbookSale!]! """ null = unlimited. """ salesPerMonthLimit: Int """ Sales recorded this calendar month (what the plan limit counts). """ salesThisMonth: Int! """ Every item sold in a year, oldest first (paid plans): not tax advice. Sales with an item waiting in review aren't included (see taxLotsInReview). """ taxLots(year: Int!): [PullbookTaxLot!]! """ Sales that year left out of taxLots because an item is waiting in review. """ taxLotsInReview(year: Int!): Int! """ The paid plan you said you're interested in. """ upgradeInterest: String } enum PullbookChannel { """ eBay: 13.25% of price and shipping + $0.30 ($0.40 over $10). """ EBAY """ A card show or local sale: no fees unless you enter them. """ IN_PERSON """ Anywhere else: no fees unless you enter them. """ OTHER """ TCGplayer: 10.75% of the item price + 2.5% of price and shipping + $0.30. """ TCGPLAYER """ Whatnot: 8% of the item price + 2.9% of price and shipping + $0.30. """ WHATNOT } """ A stream or card show. Its profit is its sales' net, minus their cost basis, minus what the event cost. """ type PullbookEvent { cost: Float! costBasis: Float! heldOn: ISO8601Date! id: ID! kind: PullbookEventKind! name: String! net: Float! """ Settled sales' net − their cost basis − the event's cost. Sales still in review aren't counted until they're settled. """ profit: Float! salesCount: Int! salesInReview: Int! } enum PullbookEventKind { """ A card show. """ SHOW """ A live stream (Whatnot, TikTok…). """ STREAM } """ Something you still hold, at market value in your ledger's currency. """ type PullbookHolding { """ The price's date. """ asOf: ISO8601Date """ What it cost you (costBasis); null when its purchase is costUnknown. """ cost: Float costUnknown: Boolean! """ value − cost; null without both. """ gain: Float item: PullbookItem! """ Cardmarket's trend (else average) times quantity, converted from euros at the rate for the price's date; null without a price or a rate. """ value: Float } type PullbookHoldingDay { date: ISO8601Date! """ What today's holdings were worth that day. """ value: Float! } type PullbookHoldingGroup { """ sealed or singles (cards and bulk). """ kind: String! quantity: Int! value: Float! } """ What you hold, what it cost and what it's worth today. Market values are estimates, not offers. """ type PullbookHoldings { """ The newest price date. """ asOf: ISO8601Date costUnknownQuantity: Int! """ Value of items from purchases marked costUnknown (in value, never in gain). """ costUnknownValue: Float! currency: String! """ On items with both a value and a known cost. """ gain: Float! """ gain as a percent of what those items cost. """ gainPercent: Float groups: [PullbookHoldingGroup!]! """ Value of today's holdings on each day with prices. """ history(days: Int = 90): [PullbookHoldingDay!]! """ What you paid for items with a known cost. """ paid: Float! """ False until exchange rates are loaded: values are null and totals 0. """ ratesLoaded: Boolean! """ Most valuable first. """ rows( """ sealed or singles. """ kind: String ): [PullbookHolding!]! """ Items with no market price (bulk, or not on Cardmarket), left out of value. """ unpricedQuantity: Int! """ Market value of everything with a price. """ value: Float! } """ An uploaded sales export. needs_mapping: its date, item and price columns weren't found by name, so call finishImport with a mapping (see headers and missingFields). running: it's being imported; read it again in a few seconds. """ type PullbookImport { channel: PullbookChannel! createdAt: ISO8601DateTime! """ Sales recorded. """ createdCount: Int! """ Orders already imported, skipped. """ duplicateCount: Int! errorCount: Int! errors: [ImportError!]! filename: String! """ The file's column names. """ headers: [String!]! id: ID! mapping: [ImportMapping!]! """ Required fields not mapped yet: sold_on, title, item_price. """ missingFields: [String!]! """ Orders not imported because the plan's monthly sales were used up. """ overLimitCount: Int! """ Sold lines waiting to be matched (viewer.pullbook.reviewQueue). """ reviewCount: Int! rowsCount: Int! """ needs_mapping, running, done or failed (failed imports can be uploaded again: recorded orders are skipped). """ status: String! } """ One line of a seller's inventory. cost is its share of the purchase's cost, split by market value; extraCost is what was spent on it alone (grading, say). Money is in the ledger's currency (Pullbook.currency). """ type PullbookItem { card: Card condition: String cost: Float! """ cost + extraCost. """ costBasis: Float! extraCost: Float! extraCostNote: String grade: String id: ID! kind: PullbookItemKind! label: String! """ An opened sealed item: no longer inventory; see its pulls. """ opened: Boolean! """ The sealed item this came out of. """ openedFromId: ID printing: Printing purchaseId: ID! quantity: Int! sealedProduct: SealedProduct sold: Boolean! """ Your value per unit for splitting cost, on the Cardmarket (€) scale; null uses the market price. """ valueOverride: Float } enum PullbookItemKind { """ A count of bulk cards. """ BULK """ A card (a hit), possibly several copies. """ CARD """ A sealed product; once opened its cost passes to its pulls. """ SEALED } """ Something a seller bought. Its totalCost (price + shipping + tax) is split across its items. """ type PullbookPurchase { """ You marked it "I don't know what I paid": its amounts are 0. """ costUnknown: Boolean! createdAt: ISO8601DateTime! id: ID! """ Everything that came with it, including pulls from opened sealed items. """ items: [PullbookItem!]! kind: PullbookPurchaseKind! name: String! notes: String price: Float! purchasedOn: ISO8601Date! quantity: Int! sealedProduct: SealedProduct shipping: Float! source: String tax: Float! totalCost: Float! """ Items with no market price, weighted as an average item. """ unpricedItems: [PullbookItem!]! } enum PullbookPurchaseKind { """ A spot in someone else's break. """ BREAK """ A mixed lot or collection. """ LOT """ A sealed product from the catalog (pass sealedProductId). """ SEALED """ Singles bought as they are. """ SINGLES } type PullbookReport { """ Net from items with no known cost: in profit at a cost of 0. """ costUnknownNet: Float! group: PullbookReportGroup! """ Sales left out because an item is waiting in review. """ inReview: Int! rows: [PullbookReportRow!]! total: PullbookReportRow! year: Int } enum PullbookReportGroup { """ Each stream or show, minus what it cost. """ EVENT """ Each month, minus that month's stream and show costs. """ MONTH """ Each card, sealed product or bulk. """ PRODUCT """ Each purchase: what it cost, what sold from it, and what's left. """ PURCHASE } """ One group's settled sales. Amounts are in your ledger's currency. """ type PullbookReportRow { """ What the items that sold cost you. """ costBasis: Float! """ PURCHASE: it's marked cost unknown, so spent, costBasis and profit aren't real figures. """ costUnknown: Boolean! """ EVENT and MONTH: what the streams and shows cost. """ eventCost: Float """ PURCHASE: the cost of what's left of it today. """ inStock: Float """ The purchase or event id, a product key (card:…, sealed:…, bulk) or the month (YYYY-MM-01); null for sales with nothing to group by. """ key: String label: String! """ What the buyers paid, after fees and shipping. """ net: Float! """ net − costBasis − eventCost. Items with no known cost count at a cost of 0. """ profit: Float! quantity: Int! sales: Int! """ PURCHASE: what it cost in all, extra costs like grading included, whatever the year. """ spent: Float } """ One order. net = gross + shippingCharged − fees − shippingCost, in your ledger currency. """ type PullbookSale { buyer: String channel: PullbookChannel! costBasis: Float! createdAt: ISO8601DateTime! event: PullbookEvent externalOrderId: String fees: Float! """ schedule, manual or csv. """ feesSource: String! gross: Float! id: ID! lines: [PullbookSaleLine!]! needsReview: Boolean! net: Float! notes: String """ null while a line is in review: its cost isn't known yet. """ profit: Float shippingCharged: Float! shippingCost: Float! soldOn: ISO8601Date! } """ One thing sold. proceeds is its share of the sale's net (split by price); profit is proceeds − cost basis. """ type PullbookSaleLine { """ Your unsold copies of this card, oldest first (for REVIEW lines). """ candidates: [PullbookItem!]! card: Card costBasis: Float id: ID! item: PullbookItem price: Float! proceeds: Float! profit: Float quantity: Int! saleId: ID! status: PullbookSaleLineStatus! title: String! } enum PullbookSaleLineStatus { """ Sold from your inventory; its cost basis is frozen. """ MATCHED """ Waiting to be matched to an item (resolveSaleLine). """ REVIEW """ Not from your ledger; the cost basis was entered by hand. """ UNMATCHED } """ One item sold: a summary of your records, not tax advice. """ type PullbookTaxLot { """ null when it wasn't from your ledger. """ acquiredOn: ISO8601Date costBasis: Float! """ From a purchase marked cost unknown: costBasis is 0 and gain is the whole proceeds, so don't report them as they are. """ costUnknown: Boolean! description: String! gain: Float! proceeds: Float! quantity: Int! soldOn: ISO8601Date! """ long (held more than a year), short, or unknown. """ term: String! } """ Pokémon TCG data: species, sets, cards and printings. Start with search or resolveId if you have a name or another system's ID. """ type Query { """ Estimate a card's condition from photos: centering and edge whitening are measured, visible damage (creases, dents, scratches, stains) is reported with locations, and they combine into a grade range with what the photos can't show. Pass the front, and the back for a narrower range, as base64, a data URL or an https URL; the card must be at least 1000 px wide in the photo, out of its sleeve if possible. """ assessCondition(back: String, front: String!): ConditionAssessment! """ One card by code, e.g. swsh3-136 or asia:SV2a-006. """ card(code: String!): Card cards( """ Returns the elements in the list that come after the specified cursor. """ after: String """ Returns the elements in the list that come before the specified cursor. """ before: String filter: CardFilter """ Returns the first _n_ elements from the list. """ first: Int """ Returns the last _n_ elements from the list. """ last: Int orderBy: CardOrder = RELEASE_DATE_DESC ): CardConnection! """ Look for signs that a card is fake. The card is identified, its printed numbers and names are compared with our catalog, and the photo with a scan of the real card (fonts, symbols, spelling, colours, finish, and the back if sent). Returns red flags and a verdict of LIKELY_FAKE, NO_RED_FLAGS or CANT_TELL; it never says a card is genuine. Pass the front (and ideally the back) as base64, a data URL or an https URL. """ checkAuthenticity(back: String, front: String!): AuthenticityCheck! """ Identify a card, and its exact printing where the photo shows it (1st Edition, Shadowless, reverse holo, stamps), from a photo. Pass the image as base64, a data URL, or an https URL (JPEG, PNG or WebP; at most 10 MB; at least 600 px on the short edge). An optional second photo tilted under a light helps tell holo from reverse. """ identifyCard(image: String!, tiltedImage: String): Identification! """ Identify every card in one photo of several: a spread on a table or a binder page (up to 20 cards). Cards are found by their outlines and returned in reading order with where each is in the photo. For a binder page whose cards touch, pass grid (e.g. "3x3") to split the photo evenly instead. Each identified card counts as one photo check; cards past your remaining checks come back with an error instead of an identification. """ identifyCards( """ Rows x columns, e.g. 3x3 for a 9-pocket page. """ grid: String image: String! ): BatchIdentification! """ Fetches an object given its ID. """ node(id: ID!): Node """ Look up a record by another system's ID. Sources: tcgdex, pokemontcg.io, tcgplayer (product id), cardmarket (idProduct). Marketplace ids can map to several printings. """ resolveId(source: String!, value: String!): [Entity!]! """ Sealed products, newest first. """ sealedProducts( """ Returns the elements in the list that come after the specified cursor. """ after: String """ Returns the elements in the list that come before the specified cursor. """ before: String """ Returns the first _n_ elements from the list. """ first: Int """ See SealedProduct.kind for values. """ kind: String """ Returns the last _n_ elements from the list. """ last: Int """ Case-insensitive substring. """ name: String region: Region setCode: String ): SealedProductConnection! """ Fuzzy name search across species, sets and cards (any spelling close to the query), best matches first. """ search(limit: Int = 20, query: String!): [Entity!]! """ All series, oldest first. """ series: [Series!]! """ One set by code, e.g. sv03.5 or asia:SV2a. """ set(code: String!): Set """ Sets, newest first. """ sets( """ Returns the elements in the list that come after the specified cursor. """ after: String """ Returns the elements in the list that come before the specified cursor. """ before: String """ false = physical sets only; true = TCG Pocket only. """ digital: Boolean """ Returns the first _n_ elements from the list. """ first: Int """ Returns the last _n_ elements from the list. """ last: Int region: Region """ Series slug, e.g. sv. """ series: String ): SetConnection! """ Where to verify a graded slab's cert number (PSA, CGC, BGS, SGC, TAG) and whether the number fits the grader's format. identifyCard fills this in from a photo of the slab label. """ slabVerification(cert: String!, grader: String!): SlabVerification! """ One species by Pokédex number or slug. """ species(nationalDex: Int, slug: String): Species """ Species in Pokédex order. """ speciesList( """ Returns the elements in the list that come after the specified cursor. """ after: String """ Returns the elements in the list that come before the specified cursor. """ before: String """ Returns the first _n_ elements from the list. """ first: Int generation: Int """ Returns the last _n_ elements from the list. """ last: Int """ Matches the default form's types, e.g. fire. """ type: String ): SpeciesConnection! """ Your account: plan, limits and usage. """ viewer: Viewer } """ One sign that a card may be fake: what the photo shows against what the real card has. """ type RedFlag { confidence: Float! expected: String! """ e.g. hp, attack_name, nonexistent_card, font, energy_symbol, spelling, colour, back. """ kind: String! seen: String! """ strong or medium. """ severity: String! """ catalog (printed text vs our data), visual (photo vs the real card's scan), back, or measured. """ source: String! } """ INTERNATIONAL sets are printed in English and European languages; ASIA sets are Japanese, Korean, Chinese, Indonesian and Thai releases with their own set lists. """ enum Region { ASIA INTERNATIONAL } """ One thing sold: an inventory item (itemId), a card (cardCode: your oldest unsold copy is used), or just a title (it waits in review). """ input SaleLineInput { cardCode: String itemId: ID """ What the buyer paid for this line, before shipping. """ price: Float! quantity: Int = 1 title: String } """ One line of what's inside a sealed product. """ type SealedContent { """ sleeves, energy, damage_dice, coin, code_card, players_guide, … """ accessoryKind: String card: Card lineType: SealedLineType! """ Set when the exact printing is known, e.g. a Pokémon Center-stamped promo. """ printing: Printing """ For SEALED lines: the product inside. """ product: SealedProduct quantity: Int! """ For PACK lines: which set's packs. """ set: Set """ The source wording for this line. """ text: String } enum SealedLineType { """ Sleeves, dice, coins, energy, code cards and the like. """ ACCESSORY """ A specific card, usually a promo. `card` is set when we know exactly which. """ CARD """ Booster packs of one set. """ PACK """ Another sealed product, e.g. the bundles inside a case. """ SEALED """ Contents that vary, e.g. assorted packs from several sets. """ VARIABLE } """ A sealed product: booster pack, box, Elite Trainer Box, tin, collection, case… """ type SealedProduct implements Node { cardmarketProductId: Int contents: [SealedContent!]! contentsStatus: ContentsStatus! """ What the contents are worth on average (packs at their set's per-pack EV, plus priced promos). Compare with price and msrp; note currencies. """ expectedValue(currency: Currency = EUR): ExpectedValue! """ ID of the object. """ id: ID! """ Product photo, hosted by TCGplayer (linked, not copied). """ image: ExternalImage """ booster_pack, sleeved_pack, booster_box, half_box, booster_bundle, etb, pc_etb (Pokémon Center ETB), blister_1, blister_3, checklane_blister, mini_tin, tin, display, build_battle, prerelease_kit, collection, premium_collection, ultra_premium_collection, deck, promo_pack, art_bundle, case """ kind: String! marketplaceLinks: [MarketplaceLink!]! msrp: Float msrpCurrency: String """ Where the MSRP comes from. Standard ETBs have no official MSRP; we use a major retailer's list price. """ msrpSource: String name: String! """ Latest Cardmarket price, when we could match the product: euros unless you ask for another currency. """ price(currency: Currency = EUR): Price region: Region! releaseDate: ISO8601Date set: Set tcgplayerProductId: Int upc: String } """ The connection type for SealedProduct. """ type SealedProductConnection { """ A list of edges. """ edges: [SealedProductEdge] """ A list of nodes. """ nodes: [SealedProduct] """ Information to aid in pagination. """ pageInfo: PageInfo! } """ An edge in a connection. """ type SealedProductEdge { """ A cursor for use in pagination. """ cursor: String! """ The item at the end of the edge. """ node: SealedProduct } """ A run of sets, e.g. Scarlet & Violet. """ type Series { name: String! sets: [Set!]! slug: String! } """ An expansion or promo set. """ type Set implements Node { """ Cards in collector-number order. """ cards( """ Returns the elements in the list that come after the specified cursor. """ after: String """ Returns the elements in the list that come before the specified cursor. """ before: String """ Returns the first _n_ elements from the list. """ first: Int """ Returns the last _n_ elements from the list. """ last: Int ): CardConnection! """ Our set id: TCGdex's id, prefixed with asia: for Asian sets. """ code: String! """ True for Pokémon TCG Pocket sets: app-only cards with no physical printing or market price. """ digital: Boolean! """ Expected value of one booster pack at today's Cardmarket prices, in euros unless you ask for another currency. """ expectedValue(currency: Currency = EUR): ExpectedValue! externalIds: [ExternalId!]! """ ID of the object. """ id: ID! legalities: Legalities! localizedNames: [LocalizedName!]! logo: Image name( """ Defaults to the set's primary language. """ locale: String ): String! """ Cards per slot in one booster pack (standard SV/ME layout unless the set differs). """ packLayout: [PackSlot!]! """ The number after the slash on cards. """ printedTotal: Int """ Code used by Pokémon TCG Online/Live, e.g. DAA. """ ptcgoCode: String """ Per-pack odds by rarity, from published opening studies. Empty when none is on file. """ pullRates: [PullRate!]! region: Region! releaseDate: ISO8601Date """ Sealed products of this set (boxes, ETBs, tins…). """ sealedProducts: [SealedProduct!]! series: Series symbol: Image tcgplayerGroupId: Int """ All cards including secret rares. """ total: Int } """ The connection type for Set. """ type SetConnection { """ A list of edges. """ edges: [SetEdge] """ A list of nodes. """ nodes: [Set] """ Information to aid in pagination. """ pageInfo: PageInfo! } """ An edge in a connection. """ type SetEdge { """ A cursor for use in pagination. """ cursor: String! """ The item at the end of the edge. """ node: Set } """ Where to verify a graded slab's cert number with its grader, and whether the number is even possible for that grader. We don't look certs up ourselves: always check the grader's own page, since a fake slab can carry a real cert copied from another card. """ type SlabVerification { cert: String! """ True when verifyUrl opens this cert; false when it's a form to fill in. """ directLink: Boolean! formatDescription: String """ False when the number can't be one of this grader's certs (a red flag); null for an unknown grader. """ formatValid: Boolean """ PSA, CGC, BGS, SGC or TAG (null if unrecognised). """ grader: String graderName: String note: String """ The grader's verification page. """ verifyUrl: String } """ A Pokémon species (one National Pokédex number). Regional, Mega and Gigantamax variants are its forms. """ type Species implements Node { """ Cards featuring this species, newest sets first. """ cards( """ Returns the elements in the list that come after the specified cursor. """ after: String """ Returns the elements in the list that come before the specified cursor. """ before: String """ Returns the first _n_ elements from the list. """ first: Int """ Also include cards where it only appears in the artwork (mostly Trainers). """ includeCameos: Boolean = false """ Returns the last _n_ elements from the list. """ last: Int ): CardConnection! """ Every species in the same evolution chain, by Pokédex number. """ evolutionLine: [Species!]! evolvesFrom: Species evolvesTo: [Species!]! forms: [Form!]! generation: Int """ e.g. Flame Pokémon. """ genus: String """ ID of the object. """ id: ID! isLegendary: Boolean! isMythical: Boolean! """ Name in every language we know. """ localizedNames: [LocalizedName!]! """ Name in the requested locale, falling back to English. """ name(locale: String): String! """ National Pokédex number. """ nationalDex: Int! """ PokéAPI identifier, e.g. mr-mime. """ slug: String! } """ The connection type for Species. """ type SpeciesConnection { """ A list of edges. """ edges: [SpeciesEdge] """ A list of nodes. """ nodes: [Species] """ Information to aid in pagination. """ pageInfo: PageInfo! } """ An edge in a connection. """ type SpeciesEdge { """ A cursor for use in pagination. """ cursor: String! """ The item at the end of the edge. """ node: Species } type Stat { """ hp, attack, defense, special-attack, special-defense, speed. """ name: String! value: Int! } """ The three kinds of card. """ enum Supertype { ENERGY POKEMON TRAINER } """ A weakness or resistance. """ type TypeModifier { type: String! """ e.g. ×2, -30. """ value: String } type UsageDay { day: ISO8601Date! requests: Int! } """ The account making this request, its plan limits and usage. """ type Viewer { """ What authenticated this request: an API key's name, or the connected app's name. """ credential: String """ Requests a day, shared by all the account's keys and connected apps. """ dailyLimit: Int! email: String! perMinuteLimit: Int! plan: String! priceAlertLimit: Int! priceAlerts: [PriceAlert!]! """ Your Pullbook seller ledger (created on first use). """ pullbook: Pullbook! """ Requests per day for the last 30 days, oldest first. """ usage: [UsageDay!]! """ Requests counted today (UTC). """ usageToday: Int! """ Photo checks (identifyCard, assessCondition) a day. """ visionPerDay: Int! visionRemaining: Int! visionUsedToday: Int! webhookEndpointLimit: Int! webhookEndpoints: [WebhookEndpoint!]! } """ Measured whitening along one edge or in one corner. """ type Wear { """ edge or corner. """ kind: String! """ left, right, top, bottom, top_left, top_right, bottom_right, bottom_left. """ location: String! """ none, light, moderate, heavy or not_measurable. """ severity: String! """ Share of the band that is worn white; null where the border is itself white or silver. """ whitening: Float } """ One POST to a webhook endpoint, retried up to 5 times with backoff. """ type WebhookDelivery { """ The price date that triggered it. """ asOf: ISO8601Date attempts: Int! createdAt: ISO8601DateTime! deliveredAt: ISO8601DateTime error: String event: String! """ Also sent as the X-RarityDB-Delivery header. """ id: ID! payload: JSON! responseCode: Int """ pending (still retrying), succeeded or failed. """ status: String! } """ An https URL that receives signed event POSTs. The signing secret is only shown when it's created or rotated. """ type WebhookEndpoint { consecutiveFailures: Int! createdAt: ISO8601DateTime! """ The 20 most recent, newest first. """ deliveries: [WebhookDelivery!]! """ Set after 5 failed deliveries in a row; cleared by the next success. """ failingSince: ISO8601DateTime id: ID! url: String! } type WebhookEndpointWithSecret { """ Verify X-RarityDB-Signature with this. Shown only now; rotate it if lost. """ secret: String! webhookEndpoint: WebhookEndpoint! }