Documentation
¶
Overview ¶
Package pokemontcgapi is a thin client for the Pokémon TCG API at https://pokemontcgapi.com: cards, sets, artists, series, sealed products, prices with stated provenance, the change feed, the reference vocabularies and photo recognition.
It has no dependencies outside the standard library. Every method takes a context.Context; list methods return a *Page that follows the API's own links.next URL, so pagination never has to be rebuilt by hand.
Index ¶
- Constants
- Variables
- type APIError
- type Artist
- type ArtistsService
- type AuthenticationError
- type BatchResult
- type Card
- type CardGetParams
- type CardImage
- type CardListParams
- type CardPrices
- type CardSet
- type CardsService
- type CatalogStatus
- type Change
- type ChangesParams
- type ChangesResponse
- type Client
- type Collection
- type CollectionMeta
- type ConnectionError
- type Grading
- type Health
- type HistoryParams
- type HistoryPoint
- type HistoryResponse
- type IdentifyOptions
- type InvalidRequestError
- type ListParams
- type MissingCard
- type Mover
- type MoversParams
- type MoversResponse
- type NextStep
- type NextStepPlan
- type NotFoundError
- type Option
- func WithAPIKey(key string) Option
- func WithBaseURL(baseURL string) Option
- func WithETagCache() Option
- func WithHTTPClient(httpc *http.Client) Option
- func WithMaxRetries(n int) Option
- func WithOnResponse(fn func(ResponseInfo)) Option
- func WithTimeout(d time.Duration) Option
- func WithUserAgent(ua string) Option
- type Page
- type PermissionDeniedError
- type PlanRequiredError
- type Price
- type PriceFilterParams
- type PriceIndex
- type PriceSourceInfo
- type PriceStats
- type PricesResponse
- type PricesService
- func (s *PricesService) Card(ctx context.Context, id string, p *PriceFilterParams) (*PricesResponse[CardPrices], error)
- func (s *PricesService) Current(ctx context.Context, ids []string, p *PriceFilterParams) (*BatchResult[CardPrices], error)
- func (s *PricesService) History(ctx context.Context, id string, p *HistoryParams) (*HistoryResponse, error)
- func (s *PricesService) Movers(ctx context.Context, p *MoversParams) (*MoversResponse, error)
- func (s *PricesService) Sources(ctx context.Context) ([]PriceSourceInfo, error)
- func (s *PricesService) Stats(ctx context.Context, id string, p *StatsParams) (*StatsResponse, error)
- type QuotaExceededError
- type RateLimitedError
- type ReferenceService
- func (s *ReferenceService) All(ctx context.Context) (map[string][]string, error)
- func (s *ReferenceService) Rarities(ctx context.Context) ([]string, error)
- func (s *ReferenceService) Subtypes(ctx context.Context) ([]string, error)
- func (s *ReferenceService) Supertypes(ctx context.Context) ([]string, error)
- func (s *ReferenceService) Types(ctx context.Context) ([]string, error)
- type ResponseInfo
- type SealedListParams
- type SealedPrices
- type SealedProduct
- type SealedService
- func (s *SealedService) Get(ctx context.Context, id string, p *SetGetParams) (*SealedProduct, error)
- func (s *SealedService) List(ctx context.Context, p *SealedListParams) (*Page[SealedProduct], error)
- func (s *SealedService) Prices(ctx context.Context, id string, p *PriceFilterParams) (*PricesResponse[SealedPrices], error)
- type SearchHint
- type Series
- type SeriesService
- type ServerError
- type SetGetParams
- type SetListParams
- type SetsService
- type StatsParams
- type StatsResponse
- type TimeoutError
- type Translation
- type TrialExpiredError
- type UpgradeRequiredError
- type VisionCandidate
- type VisionMeta
- type VisionResponse
- type VisionResult
- type VisionService
Examples ¶
Constants ¶
const ( LocaleEN = "en" LocaleFR = "fr" LocaleDE = "de" LocaleJA = "ja" LocaleIT = "it" LocaleES = "es" LocalePT = "pt" LocaleZH = "zh" )
Locale values with rows in the table (measured 2026-09-16): en, fr, de, ja, it, es, pt, zh. The API accepts ko too, but it has zero rows.
const ( RegionWest = "WEST" RegionJP = "JP" RegionCN = "CN" RegionKR = "KR" )
Print regions. KR exists in the server schema but matches no set: filtering on it returns an empty page, not an error.
const ( SourceTCGplayer = "TCGPLAYER" SourcePriceCharting = "PRICECHARTING" SourceCardmarket = "CARDMARKET" SourceCardTrader = "CARDTRADER" SourceEbay = "EBAY" SourcePTCGIndex = "PTCG_INDEX" SourceCommunity = "COMMUNITY" )
Price sources.
const ( BasisGuide = "GUIDE" BasisDerived = "DERIVED" BasisSold = "SOLD" BasisAsking = "ASKING" )
Price bases. DERIVED is computed by us; GUIDE is a figure published upstream.
const ( IncludeIndex = "index" IncludePrices = "prices" IncludeTranslations = "translations" IncludeImages = "images" IncludeSet = "set" IncludeArtist = "artist" )
Values accepted by CardGetParams.Include and CardListParams.Include.
const ( VisionMatch = "match" VisionAmbiguous = "ambiguous" VisionNoMatch = "no_match" )
Vision decisions. Ambiguous is not a failure: it is the normal case on reprints, where two printings share the illustration and cannot be told apart from the image alone.
const Version = "0.1.0"
Version is the SDK version. It travels in the User-Agent header of every request and must match the git tag of a release.
Variables ¶
var ErrTooManyIDs = errors.New("pokemontcgapi: too many ids")
ErrTooManyIDs is returned, wrapped with the count, when a batch method receives more ids than the API accepts in one request.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
// Code is the stable code of the error taxonomy, e.g. CARD_NOT_FOUND.
Code string
Status int
Message string
// RequestID is set whenever the response came from the API. Quote it in a
// support message: it is the only thing that can be looked up in the logs.
RequestID string
Details map[string]any
}
APIError is the error envelope the API returns on every 4xx and 5xx. The typed wrappers in this file (NotFoundError, RateLimitedError, ...) embed it, so errors.As works both on the wrapper and on *APIError itself.
QuotaExceededError is separate from RateLimitedError on purpose: both are 429, but a rate limit passes by waiting and an exhausted quota never does. The client retries the first and never the second.
func (*APIError) ActionURL ¶
ActionURL is the URL for the next step's action: checkout for subscribe, the account page for upgrade, the verification link for verify_email, the contact address for sales and support. Empty when there is none.
func (*APIError) CheckoutURL ¶
CheckoutURL is the subscribe checkout, when the next step carries one.
type Artist ¶
type Artist struct {
Slug string `json:"slug"`
Name string `json:"name"`
CardCount int `json:"card_count"`
// Links is set only by Artists.Get: the ready-made search for the artist's cards.
Links *struct {
Cards string `json:"cards,omitempty"`
} `json:"links,omitempty"`
}
Artist is an illustrator.
type ArtistsService ¶
type ArtistsService struct {
// contains filtered or unexported fields
}
ArtistsService wraps /v1/artists.
func (*ArtistsService) List ¶
func (s *ArtistsService) List(ctx context.Context, p *ListParams) (*Page[Artist], error)
List returns the illustrators. Select is ignored on this route.
type AuthenticationError ¶
type AuthenticationError struct{ *APIError }
AuthenticationError is a 401: the key is missing, malformed or revoked.
func (*AuthenticationError) Unwrap ¶
func (e *AuthenticationError) Unwrap() error
type BatchResult ¶
type BatchResult[T any] struct { Data []T `json:"data"` Requested int `json:"requested"` Found int `json:"found"` // Missing is absent when every requested id resolves; repeated ids appear once. Missing []MissingCard `json:"missing,omitempty"` Withheld []string `json:"withheld,omitempty"` }
BatchResult is the answer of the batch routes.
type Card ¶
type Card struct {
ID string `json:"id"`
// LegacyID is an alternate identifier in the same shape. It resolves on the same route.
LegacyID *string `json:"legacy_id"`
Name string `json:"name"`
Number string `json:"number"`
NumberSort *int `json:"number_sort"`
Supertype *string `json:"supertype"`
HP *int `json:"hp"`
Level *string `json:"level"`
EvolvesFrom *string `json:"evolves_from"`
EvolvesTo []string `json:"evolves_to"`
Rarity *string `json:"rarity"`
RegulationMark *string `json:"regulation_mark"`
SetCode string `json:"set_code"`
SetName string `json:"set_name"`
SetTotal *int `json:"set_total"`
PtcgoCode *string `json:"ptcgo_code"`
Series *string `json:"series"`
ReleaseDate *string `json:"release_date"`
PrintRegion string `json:"print_region"`
ArtistName *string `json:"artist_name"`
ArtistSlug *string `json:"artist_slug"`
// IndexEUR is the composite index in euro. Always present on a single
// card; on list and batch rows only with Include index (1 credit per 50
// cards). Without it the field is absent and Meta.Withheld contains "index".
IndexEUR *float64 `json:"index_eur,omitempty"`
LastPriceAt *string `json:"last_price_at,omitempty"`
TCGplayerID *int `json:"tcgplayer_id"`
CardmarketID *int `json:"cardmarket_id"`
// JPTwinID is the Japanese printing of the same card, where the pairing is known.
JPTwinID *string `json:"jp_twin_id"`
RowVersion int `json:"row_version"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
// Relations, only with Include.
Prices []Price `json:"prices,omitempty"`
Images []CardImage `json:"images,omitempty"`
Translations []Translation `json:"translations,omitempty"`
Set *CardSet `json:"set,omitempty"`
Artist *Artist `json:"artist,omitempty"`
// Game text. Present in English on Western printings and unevenly:
// attacks on about a third of the catalogue, nothing on Japanese and
// Chinese printings. nil means "not held", never "the card has no attacks".
Attacks []json.RawMessage `json:"attacks"`
Abilities []json.RawMessage `json:"abilities"`
Weaknesses []json.RawMessage `json:"weaknesses"`
Resistances []json.RawMessage `json:"resistances"`
Subtypes []string `json:"subtypes"`
RetreatCost []string `json:"retreat_cost"`
ConvertedRetreatCost *int `json:"converted_retreat_cost"`
Rules []string `json:"rules"`
FlavorText *string `json:"flavor_text"`
Types []string `json:"types"`
NationalPokedexNumbers []int `json:"national_pokedex_numbers"`
}
Card is one printing.
type CardGetParams ¶
CardGetParams are the parameters of Cards.Get and Cards.Batch.
type CardImage ¶
type CardImage struct {
Face string `json:"face"`
Size string `json:"size"`
Locale *string `json:"locale"`
URL string `json:"url"`
ImageSource *string `json:"image_source"`
// Width and Height are modelled but not populated: reserve space with a 5:7 ratio.
Width *int `json:"width"`
Height *int `json:"height"`
}
CardImage is one rendition of a card face.
type CardListParams ¶
type CardListParams struct {
Q string
Select []string
OrderBy string
Limit int
Cursor string
Include []string
// Lang replaces Name with the name in that locale; falls back to en.
Lang string
// Set narrows to one or more sets by code, slug or alternate id, instead of q=set.id:...
Set []string
}
CardListParams are the parameters of Cards.Search and Sets.Cards.
type CardPrices ¶
type CardPrices struct {
CardID string `json:"card_id"`
Index *PriceIndex `json:"index"`
Quotes []Price `json:"quotes"`
}
CardPrices is the index and current quotes of one card.
type CardSet ¶
type CardSet struct {
ID string `json:"id"`
Code string `json:"code"`
Slug string `json:"slug"`
LegacyID *string `json:"legacy_id"`
Name string `json:"name"`
Series *string `json:"series"`
Region string `json:"region"`
ReleaseDate *string `json:"release_date"`
Total *int `json:"total"`
PrintedTotal *int `json:"printed_total"`
PtcgoCode *string `json:"ptcgo_code"`
SymbolURL *string `json:"symbol_url"`
LogoURL *string `json:"logo_url"`
UpdatedAt string `json:"updated_at,omitempty"`
}
CardSet is one set.
type CardsService ¶
type CardsService struct {
// contains filtered or unexported fields
}
CardsService wraps /v1/cards.
func (*CardsService) Batch ¶
func (s *CardsService) Batch(ctx context.Context, ids []string, p *CardGetParams) (*BatchResult[Card], error)
Batch reads up to 100 cards in one request. The answer carries Requested and Found, and Missing when something did not resolve: one entry per id, with SuggestedID where the id is a historical alias of a card now in another set.
func (*CardsService) Get ¶
func (s *CardsService) Get(ctx context.Context, id string, p *CardGetParams) (*Card, error)
Get reads one card by id. Both the canonical id and the alternate legacy id resolve.
func (*CardsService) Search ¶
func (s *CardsService) Search(ctx context.Context, p *CardListParams) (*Page[Card], error)
Search runs a catalogue search and returns the first page, iterable to the end.
type CatalogStatus ¶
type CatalogStatus struct {
Status string `json:"status"`
Catalog struct {
Sets int `json:"sets"`
Cards int `json:"cards"`
Sealed int `json:"sealed"`
Artists int `json:"artists"`
} `json:"catalog"`
Sources []struct {
Source string `json:"source"`
LastSuccessAt *string `json:"last_success_at"`
AgeHours *float64 `json:"age_hours"`
// State is fresh, stale, critical or never_run.
State string `json:"state"`
} `json:"sources"`
Upstream struct {
ContractOK bool `json:"contract_ok"`
Error *string `json:"error"`
} `json:"upstream"`
Version string `json:"version"`
}
CatalogStatus is the answer of /v1/status: counts and freshness per source.
type Change ¶
type Change struct {
ID int64 `json:"id"`
// Kind is SET, CARD, ...: the real list is change_kinds in /v1/reference.
Kind string `json:"kind"`
EntityID string `json:"entity_id"`
Op string `json:"op"`
Version int `json:"version"`
ChangedAt string `json:"changed_at"`
}
Change is one row of the incremental feed.
type ChangesParams ¶
type ChangesParams struct {
// Since is the last next_since received. Zero means from the oldest available.
Since int64
Kind string
Limit int
}
ChangesParams are the parameters of Client.Changes.
type ChangesResponse ¶
type ChangesResponse struct {
Data []Change `json:"data"`
Meta struct {
Count int `json:"count"`
HasMore bool `json:"has_more"`
// NextSince is to be stored and sent back as Since: the feed has no other state.
NextSince int64 `json:"next_since"`
Watermark int64 `json:"watermark"`
OldestAvailable int64 `json:"oldest_available"`
Behind int64 `json:"behind"`
} `json:"meta"`
Links *struct {
Next string `json:"next,omitempty"`
} `json:"links,omitempty"`
}
ChangesResponse is the answer of Client.Changes.
type Client ¶
type Client struct {
Cards *CardsService
Sets *SetsService
Artists *ArtistsService
Series *SeriesService
Sealed *SealedService
Prices *PricesService
Reference *ReferenceService
Vision *VisionService
// contains filtered or unexported fields
}
Client is the entry point. Resources mirror the API paths (client.Cards.Get, client.Sets.Cards) so that going from the documentation to the code needs no conversion table. Every list method returns a *Page that walks the collection by following links.next.
client := pokemontcgapi.New(pokemontcgapi.WithAPIKey(os.Getenv("PTCG_API_KEY")))
card, err := client.Cards.Get(ctx, "base1-4", &pokemontcgapi.CardGetParams{Include: []string{"prices"}})
Example ¶
ExampleClient needs PTCG_API_KEY in the environment; it is compiled, not run.
ctx := context.Background()
client := pokemontcgapi.New() // reads PTCG_API_KEY
card, err := client.Cards.Get(ctx, "base1-4", &pokemontcgapi.CardGetParams{Include: []string{pokemontcgapi.IncludePrices}})
if err != nil {
var notFound *pokemontcgapi.NotFoundError
if errors.As(err, ¬Found) {
log.Fatalf("no such card: %s", notFound.Message)
}
log.Fatal(err)
}
fmt.Println(card.ID, card.Name)
page, err := client.Sets.List(ctx, &pokemontcgapi.SetListParams{Region: pokemontcgapi.RegionJP, Limit: 250})
if err != nil {
log.Fatal(err)
}
for set, err := range page.All(ctx) {
if err != nil {
log.Fatal(err)
}
fmt.Println(set.Code, set.Name)
}
func New ¶
New builds a client. The transport is the standard library's; there are no dependencies to carry.
func (*Client) Changes ¶
func (c *Client) Changes(ctx context.Context, p *ChangesParams) (*ChangesResponse, error)
Changes reads the incremental feed: what changed after Since. Store Meta.NextSince and send it back on the next call.
func (*Client) Health ¶
Health is the liveness probe. Separate from Status: a stalled ingest is not a service down.
func (*Client) LastResponse ¶
func (c *Client) LastResponse() *ResponseInfo
LastResponse returns the headers of the last response this client received, or nil before the first one. With concurrent calls it is the last to arrive: to count them all, use WithOnResponse.
type Collection ¶
type Collection[T any] struct { Data []T `json:"data"` Meta CollectionMeta `json:"meta"` Links *struct { Next string `json:"next,omitempty"` } `json:"links,omitempty"` }
Collection is the envelope of every list route.
type CollectionMeta ¶
type CollectionMeta struct {
Limit int `json:"limit"`
Count int `json:"count"`
TotalCount *int `json:"total_count,omitempty"`
HasMore bool `json:"has_more"`
// Withheld names what the response left out: "index" when select names
// index_eur without Include index, or the price rows the plan does not cover.
Withheld []string `json:"withheld,omitempty"`
// Warnings are grace-period parameter warnings; distinct from search hints.
Warnings []string `json:"warnings,omitempty"`
// Hints are present when a search by number or set name has a useful suggestion.
Hints []SearchHint `json:"hints,omitempty"`
}
CollectionMeta describes a page of a collection.
type ConnectionError ¶
ConnectionError means the request never got an answer: DNS, TLS, socket.
func (*ConnectionError) Error ¶
func (e *ConnectionError) Error() string
func (*ConnectionError) Unwrap ¶
func (e *ConnectionError) Unwrap() error
type Health ¶
type Health struct {
Status string `json:"status"`
DB bool `json:"db"`
UptimeS float64 `json:"uptime_s"`
Version string `json:"version"`
}
Health is the liveness probe.
type HistoryParams ¶
type HistoryParams struct {
Source string
Variant string
Locale string
Printing string
// From and To are YYYY-MM-DD. A window wider than the plan gives *UpgradeRequiredError.
From string
To string
Bucket string // day, week or month
}
HistoryParams are the parameters of Prices.History.
type HistoryPoint ¶
type HistoryPoint struct {
Date string `json:"date"`
Source string `json:"source"`
Variant string `json:"variant"`
Locale *string `json:"locale"`
Printing *string `json:"printing"`
Amount float64 `json:"amount"`
Currency string `json:"currency"`
SampleN *int `json:"sample_n"`
}
HistoryPoint is one bucket of the price history.
type HistoryResponse ¶
type HistoryResponse struct {
Data []HistoryPoint `json:"data"`
Meta struct {
CardID string `json:"card_id"`
From string `json:"from"`
To string `json:"to"`
Bucket string `json:"bucket"`
Count int `json:"count"`
Truncated bool `json:"truncated"`
Capped bool `json:"capped"`
// PlanWindowDays is nil when the plan gives the whole history.
PlanWindowDays *int `json:"plan_window_days"`
} `json:"meta"`
}
HistoryResponse is the answer of Prices.History.
type IdentifyOptions ¶
type IdentifyOptions struct {
// TopK is how many candidates, 1..10.
TopK int
// Set restricts to one set. It is the hint that resolves a reprint.
Set string
// Region restricts to a print region. Same purpose.
Region string
}
IdentifyOptions narrow a photo recognition.
type InvalidRequestError ¶
type InvalidRequestError struct{ *APIError }
InvalidRequestError is a 400 or 422: the request is wrong. Field names the parameter when the API says which one.
func (*InvalidRequestError) Field ¶
func (e *InvalidRequestError) Field() string
Field is details.field, when present.
func (*InvalidRequestError) Unwrap ¶
func (e *InvalidRequestError) Unwrap() error
type ListParams ¶
ListParams are the parameters shared by the simple list routes.
Q is the search grammar. Field names there are camelCase and dotted (set.code, nationalPokedexNumbers) while response keys are snake_case (set_code): two vocabularies, and mixing them gives a 400 listing the valid ones.
type MissingCard ¶
type MissingCard struct {
ID string `json:"id"`
// SuggestedID is present only for an existing historical alias in a different canonical set.
SuggestedID string `json:"suggested_id,omitempty"`
}
MissingCard is one id a batch could not resolve.
type Mover ¶
type Mover struct {
CardID string `json:"card_id"`
Name string `json:"name"`
SetCode string `json:"set_code"`
From float64 `json:"from"`
To float64 `json:"to"`
ChangePct float64 `json:"change_pct"`
Currency string `json:"currency"`
}
Mover is one card in the movers list.
type MoversParams ¶
type MoversParams struct {
Window string
Direction string // gainers or losers
// MinValue in euro keeps cards worth a few cents out.
MinValue float64
Locale string
// Limit is 1..50.
Limit int
}
MoversParams are the parameters of Prices.Movers.
type MoversResponse ¶
type MoversResponse struct {
Data []Mover `json:"data"`
Meta struct {
Window string `json:"window"`
From string `json:"from"`
To string `json:"to"`
Direction string `json:"direction"`
MinValue float64 `json:"min_value"`
Count int `json:"count"`
Source string `json:"source"`
} `json:"meta"`
}
MoversResponse is the answer of Prices.Movers.
type NextStep ¶
type NextStep struct {
Action string // subscribe, upgrade, contact_sales, contact_support, verify_email
Actor string // always account_owner
Plan *NextStepPlan
CheckoutURL string
CheckoutURLYearly string
ManageURL string
ContactURL string
VerifyURL string
PlansURL string
Handoff string
}
NextStep is the human handoff attached to commercial refusals (details.next_step): what the account owner has to do, and where.
type NextStepPlan ¶
type NextStepPlan struct {
Code string
Name string
MonthlyEUR string
YearlyEUR string
CreditsPerMonth *int
}
NextStepPlan describes the plan a next step points at, when the API names one.
type NotFoundError ¶
type NotFoundError struct{ *APIError }
NotFoundError is a 404, or any code ending in _NOT_FOUND. Not a network error: it is never retried.
func (*NotFoundError) Unwrap ¶
func (e *NotFoundError) Unwrap() error
type Option ¶
type Option func(*Client)
Option configures a Client.
func WithAPIKey ¶
WithAPIKey sets the key. Without it, PTCG_API_KEY is read from the environment.
func WithBaseURL ¶
WithBaseURL points the client somewhere else, e.g. a test server.
func WithETagCache ¶
func WithETagCache() Option
WithETagCache remembers ETags and sends If-None-Match. Worth it: a 304 has no body and costs no quota, so a mirror that re-syncs often pays only for the pages that changed. The cache is in memory and per client, on purpose.
func WithHTTPClient ¶
WithHTTPClient injects the transport. Its Timeout is not used: the SDK applies its own per-attempt timeout through the context.
func WithMaxRetries ¶
WithMaxRetries sets how many times a GET is retried after the first attempt. 0 disables.
func WithOnResponse ¶
func WithOnResponse(fn func(ResponseInfo)) Option
WithOnResponse registers a callback for every response received, error responses included: the place for a credit counter.
func WithTimeout ¶
WithTimeout sets the timeout of a single attempt, not of the whole call.
func WithUserAgent ¶
WithUserAgent replaces the default User-Agent.
type Page ¶
type Page[T any] struct { Data []T Meta CollectionMeta // contains filtered or unexported fields }
Page is one page of a collection that knows how to fetch the next one.
The cursor in links.next carries a signature of the sort order, so it must never be rebuilt by hand: Next requests exactly the URL the API returned, which is the failure mode this type exists to avoid.
func (*Page[T]) All ¶
All walks every item of every page, starting from this one.
for card, err := range page.All(ctx) {
if err != nil { return err }
...
}
func (*Page[T]) Collect ¶
Collect materialises up to max items. max is mandatory because the catalogue has tens of thousands of cards, and an unbounded collect is the fastest way to fill a process's memory by mistake.
type PermissionDeniedError ¶
type PermissionDeniedError struct{ *APIError }
PermissionDeniedError is a 403: the key is valid but may not do this.
func (*PermissionDeniedError) Unwrap ¶
func (e *PermissionDeniedError) Unwrap() error
type PlanRequiredError ¶
type PlanRequiredError struct{ *PermissionDeniedError }
PlanRequiredError is 403 PLAN_REQUIRED: the route is not in the plan (movers and photo recognition start at Growth). It unwraps to *PermissionDeniedError, so code that catches that keeps working.
func (*PlanRequiredError) Unwrap ¶
func (e *PlanRequiredError) Unwrap() error
type Price ¶
type Price struct {
Source string `json:"source"`
Variant string `json:"variant"`
Basis string `json:"basis"`
// Amount is the figure, with its currency in the sibling field.
Amount float64 `json:"amount"`
Currency string `json:"currency"`
Locale *string `json:"locale"`
Condition *string `json:"condition"`
Printing *string `json:"printing"`
Grading *Grading `json:"grading"`
// AsOf is the day the observation refers to. Never today: every source is delayed.
AsOf string `json:"as_of"`
// SampleN is how many observations sit behind the figure, where the source says.
SampleN *int `json:"sample_n"`
// Provenance is the attribution string to print next to the number.
Provenance string `json:"provenance"`
}
Price is one observed price row: who saw it, on what basis, in which currency, for which printing and condition, and on which day.
type PriceFilterParams ¶
PriceFilterParams narrow a price read to a source, variant or locale.
type PriceIndex ¶
type PriceIndex struct {
EUR float64 `json:"eur"`
AsOf string `json:"as_of"`
SampleN *int `json:"sample_n"`
// ByLocale has one series per (locale, printing): the head index is the English one.
ByLocale []struct {
Locale string `json:"locale"`
Printing *string `json:"printing"`
EUR float64 `json:"eur"`
AsOf string `json:"as_of"`
SampleN *int `json:"sample_n"`
} `json:"by_locale"`
}
PriceIndex is the composite index of a card, with one series per (locale, printing).
type PriceSourceInfo ¶
type PriceSourceInfo struct {
Source string `json:"source"`
Label string `json:"label"`
MinDelayHours int `json:"min_delay_hours"`
IsOwn bool `json:"is_own"`
}
PriceSourceInfo describes one price source and its declared delay.
type PriceStats ¶
type PriceStats struct {
Window string `json:"window"`
From string `json:"from"`
To string `json:"to"`
Low *float64 `json:"low"`
High *float64 `json:"high"`
Median *float64 `json:"median"`
First *float64 `json:"first"`
Last *float64 `json:"last"`
ChangePct *float64 `json:"change_pct"`
SampleN int `json:"sample_n"`
Currency string `json:"currency"`
}
PriceStats summarises the index over a window.
type PricesResponse ¶
type PricesResponse[T any] struct { Data T `json:"data"` Meta struct { Quotes int `json:"quotes"` DelayedHours int `json:"delayed_hours"` // Withheld names the rows the plan does not cover: graded, non_english_locales. Absent if nothing is withheld. Withheld []string `json:"withheld,omitempty"` } `json:"meta"` }
PricesResponse is the envelope of the dedicated price routes.
type PricesService ¶
type PricesService struct {
// contains filtered or unexported fields
}
PricesService wraps the dedicated price routes.
Every row says where it comes from (Source), what it rests on (Basis: sold, asking, guide, derived) and which day it is for (AsOf). The rows the plan does not cover are missing from the body: LastResponse().PlanWithheld says which.
func (*PricesService) Card ¶
func (s *PricesService) Card(ctx context.Context, id string, p *PriceFilterParams) (*PricesResponse[CardPrices], error)
Card returns the index and current quotes of one card. 2 credits.
func (*PricesService) Current ¶
func (s *PricesService) Current(ctx context.Context, ids []string, p *PriceFilterParams) (*BatchResult[CardPrices], error)
Current returns up to 50 cards in one call, 4 credits per 25.
func (*PricesService) History ¶
func (s *PricesService) History(ctx context.Context, id string, p *HistoryParams) (*HistoryResponse, error)
History returns the daily history. 5 credits. The window depends on the plan (7 days on the trial, 30 on Developer, everything from Growth): asking for a wider one gives *UpgradeRequiredError with PermittedWindow.
func (*PricesService) Movers ¶
func (s *PricesService) Movers(ctx context.Context, p *MoversParams) (*MoversResponse, error)
Movers returns the cards that moved the most. 3 credits, from the Growth plan (*PlanRequiredError below it).
func (*PricesService) Sources ¶
func (s *PricesService) Sources(ctx context.Context) ([]PriceSourceInfo, error)
Sources lists the price sources with the declared delay of each. Free.
func (*PricesService) Stats ¶
func (s *PricesService) Stats(ctx context.Context, id string, p *StatsParams) (*StatsResponse, error)
Stats returns low, high, median and change of the index over a window. 2 credits.
type QuotaExceededError ¶
type QuotaExceededError struct{ *APIError }
QuotaExceededError is a 429 for an exhausted period quota: it does NOT pass by waiting, and the client never retries it.
func (*QuotaExceededError) Unwrap ¶
func (e *QuotaExceededError) Unwrap() error
type RateLimitedError ¶
type RateLimitedError struct {
*APIError
// RetryAfter is the wait the API asked for, valid when HasRetryAfter is true.
RetryAfter time.Duration
HasRetryAfter bool
}
RateLimitedError is a 429 with Retry-After: it passes by waiting.
func (*RateLimitedError) Unwrap ¶
func (e *RateLimitedError) Unwrap() error
type ReferenceService ¶
type ReferenceService struct {
// contains filtered or unexported fields
}
ReferenceService reads the vocabularies, to populate a UI's filters without guessing strings. One network request per client no matter how many of the methods are called: the answer is the same and is kept for the life of the client. A failed request is not kept, so the next call tries again.
func (*ReferenceService) All ¶
All returns every vocabulary at once: besides the four below, locales, print_regions, conditions, printings, grading_companies, price_variants, price_bases, change_kinds and the others /v1/reference lists.
func (*ReferenceService) Rarities ¶
func (s *ReferenceService) Rarities(ctx context.Context) ([]string, error)
Rarities returns the rarities.
func (*ReferenceService) Subtypes ¶
func (s *ReferenceService) Subtypes(ctx context.Context) ([]string, error)
Subtypes returns the card subtypes.
func (*ReferenceService) Supertypes ¶
func (s *ReferenceService) Supertypes(ctx context.Context) ([]string, error)
Supertypes returns the card supertypes.
type ResponseInfo ¶
type ResponseInfo struct {
URL string
Status int
RequestID string
// ErrorCode equals the error's Code on API errors; empty on success.
ErrorCode string
// CreditsCost is the credits charged by this call. 0 on free routes, 304s and client errors.
CreditsCost *int
QuotaLimit *int
QuotaRemaining *int
QuotaReset string
RateLimitRemaining *int
PlanWithheld []string
// TrialExpiresAt is set on trial keys only.
TrialExpiresAt string
}
ResponseInfo is what the response says in its headers and the body does not carry: what the call cost, what is left of the quota, and what the plan withheld. PlanWithheld is why it exists: on Cards.Get with Include prices, the rows the plan does not cover are missing from the body in silence, and only the X-Plan-Withheld header says so.
type SealedListParams ¶
type SealedListParams struct {
Q string
Set []string
Kind string
Lang string
Include []string
OrderBy string
Limit int
Cursor string
}
SealedListParams are the parameters of Sealed.List.
type SealedPrices ¶
type SealedPrices struct {
SealedID string `json:"sealed_id"`
Index *PriceIndex `json:"index"`
Quotes []Price `json:"quotes"`
}
SealedPrices is the current quotes of one sealed product. Index is always nil: the composite index does not cover sealed products.
type SealedProduct ¶
type SealedProduct struct {
ID string `json:"id"`
SKU string `json:"sku"`
Slug string `json:"slug"`
Name string `json:"name"`
// Kind is BOOSTER_BOX and the like.
Kind string `json:"kind"`
SetCode *string `json:"set_code"`
SetName *string `json:"set_name"`
ImageURL *string `json:"image_url"`
ReleaseDate *string `json:"release_date"`
PackCount *int `json:"pack_count"`
Languages []string `json:"languages"`
// IndexEUR is on lists only with Include index; on the single product always.
IndexEUR *float64 `json:"index_eur,omitempty"`
LastPriceAt *string `json:"last_price_at,omitempty"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
SealedProduct is a booster box, ETB, tin, blister or collection.
type SealedService ¶
type SealedService struct {
// contains filtered or unexported fields
}
SealedService wraps /v1/sealed: booster boxes, ETBs, tins, blisters, collections.
func (*SealedService) Get ¶
func (s *SealedService) Get(ctx context.Context, id string, p *SetGetParams) (*SealedProduct, error)
Get reads one sealed product.
func (*SealedService) List ¶
func (s *SealedService) List(ctx context.Context, p *SealedListParams) (*Page[SealedProduct], error)
List returns sealed products.
func (*SealedService) Prices ¶
func (s *SealedService) Prices(ctx context.Context, id string, p *PriceFilterParams) (*PricesResponse[SealedPrices], error)
Prices returns the current quotes of a product. 2 credits. The composite index does not cover sealed products: Data.Index is nil.
type SearchHint ¶
type SearchHint struct {
Code string `json:"code"`
Message string `json:"message"`
Received string `json:"received,omitempty"`
Matched string `json:"matched,omitempty"`
SuggestedQ string `json:"suggested_q,omitempty"`
// Matches is capped at 50; read AtLeast when the real count is higher.
Matches int `json:"matches,omitempty"`
AtLeast bool `json:"at_least,omitempty"`
SetCode string `json:"set_code,omitempty"`
SetName string `json:"set_name,omitempty"`
}
SearchHint is one search suggestion. Code says which fields are filled: NUMBER_NORMALIZED (Received, Matched), TRY_POKEDEX_NUMBER (SuggestedQ, Matches, AtLeast), SET_ALIAS_MATCHED / SET_WORDS_MATCHED (Matched), SET_ALIAS_ELSEWHERE (SetCode, SetName).
type Series ¶
type Series struct {
ID string `json:"id"`
Slug string `json:"slug"`
Name string `json:"name"`
SetCount int `json:"set_count"`
}
Series is one series (Scarlet & Violet, Sword & Shield, ...).
type SeriesService ¶
type SeriesService struct {
// contains filtered or unexported fields
}
SeriesService wraps /v1/series.
func (*SeriesService) List ¶
func (s *SeriesService) List(ctx context.Context, p *ListParams) (*Page[Series], error)
List returns the series (Scarlet & Violet, Sword & Shield, ...) with their set counts. Only OrderBy, Limit and Cursor apply on this route.
type ServerError ¶
type ServerError struct{ *APIError }
ServerError is any 5xx.
func (*ServerError) Unwrap ¶
func (e *ServerError) Unwrap() error
type SetGetParams ¶
type SetGetParams struct {
Lang string
}
SetGetParams are the parameters of Sets.Get and Sealed.Get.
type SetListParams ¶
type SetListParams struct {
Q string
OrderBy string
Limit int
Cursor string
Region string
Series string
Lang string
}
SetListParams are the parameters of Sets.List.
type SetsService ¶
type SetsService struct {
// contains filtered or unexported fields
}
SetsService wraps /v1/sets.
func (*SetsService) Cards ¶
func (s *SetsService) Cards(ctx context.Context, code string, p *CardListParams) (*Page[Card], error)
Cards returns the cards of one set, in collection order. The Set field of the params is ignored: the set is the one in the path.
func (*SetsService) Get ¶
func (s *SetsService) Get(ctx context.Context, code string, p *SetGetParams) (*CardSet, error)
Get reads one set by code, slug or alternate id.
func (*SetsService) List ¶
func (s *SetsService) List(ctx context.Context, p *SetListParams) (*Page[CardSet], error)
List returns the sets. Region is the filter worth knowing: JP returns the Japanese releases, which are the largest part of the catalogue and not translations of the Western ones.
type StatsParams ¶
StatsParams are the parameters of Prices.Stats.
type StatsResponse ¶
type StatsResponse struct {
Data PriceStats `json:"data"`
Meta struct {
CardID string `json:"card_id"`
Source string `json:"source"`
} `json:"meta"`
}
StatsResponse is the answer of Prices.Stats.
type TimeoutError ¶
type TimeoutError struct {
*ConnectionError
Timeout time.Duration
}
TimeoutError means the request was abandoned by the client after Timeout. It unwraps to *ConnectionError.
func (*TimeoutError) Error ¶
func (e *TimeoutError) Error() string
func (*TimeoutError) Unwrap ¶
func (e *TimeoutError) Unwrap() error
type Translation ¶
Translation is a card name in one locale.
type TrialExpiredError ¶
type TrialExpiredError struct{ *PermissionDeniedError }
TrialExpiredError is 403 TRIAL_EXPIRED: the trial is over and the route costs credits. Waiting and retrying do not help; a plan does.
func (*TrialExpiredError) Unwrap ¶
func (e *TrialExpiredError) Unwrap() error
type UpgradeRequiredError ¶
type UpgradeRequiredError struct{ *APIError }
UpgradeRequiredError is 403 UPGRADE_REQUIRED: the window asked for is wider than the plan allows.
func (*UpgradeRequiredError) PermittedWindow ¶
func (e *UpgradeRequiredError) PermittedWindow() any
PermittedWindow is the window the current plan grants, when the API says.
func (*UpgradeRequiredError) Unwrap ¶
func (e *UpgradeRequiredError) Unwrap() error
type VisionCandidate ¶
type VisionCandidate struct {
ID string `json:"id"`
Name string `json:"name"`
Number string `json:"number"`
Set struct {
Code string `json:"code"`
Name string `json:"name"`
PrintRegion string `json:"print_region"`
} `json:"set"`
Rarity *string `json:"rarity"`
ImageURL *string `json:"image_url"`
// Distance is a Hamming distance, 0..512: real matches sit under 150 even on a noisy photo, and nothing above 170 is returned.
Distance int `json:"distance"`
// Confidence is the same information rescaled to 0..1.
Confidence float64 `json:"confidence"`
}
VisionCandidate is one ranked candidate.
type VisionMeta ¶
type VisionMeta struct {
Count int `json:"count"`
CardsIndexed int `json:"cards_indexed"`
IndexBuiltAt string `json:"index_built_at"`
IndexLoadedAt string `json:"index_loaded_at"`
SignatureVersion int `json:"signature_version"`
// RegionsDetected is how many card-like quadrilaterals were isolated. Zero with a no_match means the card was not found in the photo, not that it is not in the catalogue.
RegionsDetected int `json:"regions_detected"`
HypothesesTried int `json:"hypotheses_tried"`
ElapsedMs int `json:"elapsed_ms"`
OCR *struct {
Applied bool `json:"applied"`
Eligible int `json:"eligible"`
Level int `json:"level,omitempty"`
Number int `json:"number,omitempty"`
Ms int `json:"ms"`
CropMs int `json:"crop_ms"`
Reason string `json:"reason,omitempty"`
SetCode string `json:"set_code,omitempty"`
SetReason string `json:"set_reason,omitempty"`
} `json:"ocr,omitempty"`
}
VisionMeta describes how the recognition went.
type VisionResponse ¶
type VisionResponse struct {
Data VisionResult `json:"data"`
Meta VisionMeta `json:"meta"`
}
VisionResponse is the answer of Vision.Identify.
type VisionResult ¶
type VisionResult struct {
Decision string `json:"decision"`
DecisionReason string `json:"decision_reason"` // clear, reprint, close_call, none, ocr_number, ocr_set_number
// ID is set ONLY when Decision is match. Otherwise nil.
ID *string `json:"id"`
Candidates []VisionCandidate `json:"candidates"`
}
VisionResult is the outcome of a photo recognition.
type VisionService ¶
type VisionService struct {
// contains filtered or unexported fields
}
VisionService recognises a card from a photograph.
It costs 25 credits a call against 1 for a read: it is the only route that does not return a row but the outcome of a comparison against the whole image index. Worth knowing before putting it in a loop.
func (*VisionService) Identify ¶
func (s *VisionService) Identify(ctx context.Context, image io.Reader, opts *IdentifyOptions) (*VisionResponse, error)
Identify sends a photo and returns the ranked candidates.
Read Data.Decision before Data.ID. ID is set only on a match; on ambiguous it is nil on purpose, because two printings of the same illustration cannot be told apart from the image alone and picking one means being wrong half the time, on exactly the cards that are worth the most. If your flow knows the set (whoever inventories a just-opened pack does), pass it in IdentifyOptions.Set: that is what resolves the tie.