# Restrike Docs How the Restrike gold coin catalogue is built: the philosophy, where the data comes from, and the public API that serves all of it. # Overview [Restrike](https://restrike.co) is a reference catalogue of gold coins: every type described to the same specification, with the melt value of each at today's spot price. This documentation explains the thinking behind the catalogue, where its data comes from, and how to read all of it programmatically. ## What is here * **[Philosophy](/philosophy)**: why the catalogue exists and the principles it is built on. * **[Where the data comes from](/data)**: how the catalogue is authored and kept clean, and the shape of [the catalogue](/data/catalogue) in Numista's vocabulary. * **[The API](/api/quickstart)**: everything the catalogue knows, as JSON, with no key and no account, plus the [interactive reference](https://docs.restrike.co/api/reference) generated from the OpenAPI document. :::tip[In a hurry?] The API needs no sign-up. `curl 'https://api.restrike.co/v1/types?q=krugerrand'` finds a type; the [quickstart](/api/quickstart) takes it from there. ::: # Philosophy Restrike is built on a premise that is narrow: **describe every gold coin to the same specification**, so that two of them can be compared without first translating between a mint's brochure, a dealer's listing and a catalogue's shorthand. ## The problem Look up the same coin on three sites and you get three different documents. One gives the gross weight but not the fine gold. One says "22 carat" and never states the fineness. One quotes a price and never says which year or which mint. None of them agree on what a "type" is, or where the line between a type and an issue falls. That is fine when you are reading about one coin. It falls apart the moment you want to answer a comparative question: which of these two carries more gold, what does a quarter-ounce of each cost at spot, which mints struck this design in 1925. Every one of those questions requires the same fields, filled in the same way, for both coins. So that is what the catalogue is: the same fields, filled in the same way. ## The principles **One specification.** A type is the unit of description. One design at one denomination and composition, one record: fine gold, fineness, gross weight, diameter, thickness, shape, orientation, both faces and the edge, catalogue references, and every issue by year, mint and finish. Two types are directly comparable field by field, with no translation step. Everything else on the site is downstream of this rule. **Numista's words.** The vocabulary is [Numista's](https://en.numista.com) (issuer, series, type, issue, mint) because it is the one the trade already shares. Every type filed there carries its N#, so a reader can check a record against the reference the trade uses. Numista's data is not copied here; the catalogue is authored from mint publications and the standard references. **Melt value, said as such.** Every type page prints the fine gold in the coin at today's spot price, in the reader's display currency. It is stated as exactly that. It is not a valuation, it carries no numismatic premium, and it is not a price anyone is asking. **Reference data over opinion.** The catalogue records facts about types, not judgements about individual physical coins: no valuations, no grading, no authentication, no provenance. **Open by design.** A structured catalogue whose whole value is that its fields are consistent should not be locked behind a rendering of those fields. The catalogue is fully readable over a [public API](/api/quickstart) with no key and no account, every page of restrike.co is also served as markdown to any client that asks, and this documentation follows the same rule. If you want to compare two coins programmatically, you should not have to scrape a page to do it. ## What Restrike is not It is not a dealer: nothing here sells a coin, and no figure on the site is an offer. It is not a valuation service. It is not a grading or authentication service, and no data here can tell you whether a specific physical coin is genuine. And it is not a forum; there is no community layer and none is planned. ## Contact Corrections, additions and questions: [hello@restrike.co](mailto\:hello@restrike.co). Catalogue corrections are the most useful thing you can send: say which type, which field, and what it should be. # Where the data comes from Restrike is authored, not scraped, and that is a decision rather than a limitation. ## The catalogue: from the mints and the references Every record starts from what the issuing mint publishes about its own coins: specification sheets, mintage reports, the technical pages of the Royal Mint, the South African Mint, the Royal Canadian Mint and their peers. Historic types are checked against the standard references (Krause's *Standard Catalog of World Coins*, Friedberg's *Gold Coins of the World*) and the catalogue numbers are recorded on the type so a reader can follow the trail. That material arrives in as many formats as there are mints, so the work is normalisation: every type is rewritten into the one specification the whole catalogue shares. Where a published figure is incomplete or ambiguous, the field is left empty. An empty field is honest; a guessed one poisons every comparison that touches it. ## Numista, and why it is not copied The vocabulary is [Numista's](https://en.numista.com), and every type filed there carries its N#. Numista's own data is not imported, by API or otherwise: its API licence and its terms of use both forbid bulk reuse, and a catalogue built on someone else's records would be theirs to withdraw. The identifier is a pointer, not a copy. ## The spot price Melt values come from a gold price feed read continuously by the API and published at `GET /spot`, per gram and per troy ounce in USD. The conversion into other display currencies uses the same ECB table `GET /rates` publishes, so a client doing the arithmetic itself lands on the same figure the pages show. ## Images Photographs arrive from mints and archives against as many different backgrounds; lined up in a grid, the eye reads the backgrounds before it reads the coins. So every image is cut out, squared, credited to its source and re-hosted on the Restrike CDN, and the site renders the processed version. Source images are never hotlinked; the same courtesy is asked of anyone [building on the API](/api/terms). ## Corrections The pipeline is built to be corrected. If a field is wrong, say which type, which field, and what it should be: [hello@restrike.co](mailto\:hello@restrike.co). # The catalogue The reference layer is a hierarchy with one thing cutting across it: ``` Issuer (a tree) ──► Series ──► Type ──► Issue │ │ └──────► Mint ◄────┘ ``` ## Issuers, series, types, issues An **issuer** is the authority that struck the coin. Issuers form a tree, the way Numista files them: Germany above Prussia and Bavaria, the United Kingdom above nothing. Only the root of a tree has a page; the leaf is stated on the type. A **series** is a design family within an issuer: the Krugerrand, the Gold Maple Leaf, the Sovereign. A series names the mint that strikes it. A **type** is the unit of description: one design at one denomination and composition. Its record carries the fields the whole catalogue agrees on: fine gold in grams, fineness, gross weight, diameter, thickness, shape, technique, die orientation, both faces and the edge (description, lettering, engravers), catalogue references, tags, and pictures. An **issue** is one year, mint and finish of a type: the 1925 Sovereign struck at Pretoria, the 1967 proof Krugerrand. It carries the mintage, the mint letter, any privy marks and the variety. A type still struck has an open-ended year range and gains an issue a year. ## Mints A **mint** is catalogued once, with its letter, and linked from both ends: a series names the mint that strikes it, and an issue names the mint that struck that year when it differs (the Sovereign's branch mints). A mint's page lists every series it strikes and every type it has struck. ## Slugs and addresses Every entity has a stable, human-readable slug, and the catalogue's URL grammar is consistent between the site and the API. A type slug is unique within its series, and a series slug within its root issuer's tree, so the address is always the triple: | Entity | On restrike.co | On the API | |---|---|---| | Issuer | `restrike.co/coins/{issuer}` | `/v1/issuers/{slug}` | | Series | `restrike.co/coins/{issuer}/{series}` | `/v1/issuers/{issuerSlug}/series/{seriesSlug}` | | Type | `restrike.co/coins/{issuer}/{series}/{type}` | `/v1/types/{issuerSlug}/{seriesSlug}/{slug}` | | Mint | `restrike.co/mints/{mint}` | `/v1/mints/{slug}` | `{issuer}` is always the **root** of the tree: a Prussian 20 Mark lives under `/coins/germany/…`. Treat the slug triple, not the title, as the address. ## Derived labels Two labels are computed from the record rather than stored, the same way on the API, in the search index and on the pages: the **size** (the dealers' bullion sizes, "1 oz" to "1/50 oz", within one percent of a troy ounce fraction; historic denominations that match none are "other") and the **purity** (24k for four nines, 22k for crown gold). Filter on either in search. # Quickstart Everything the catalogue knows is available as JSON. The public endpoints need **no key, no account and no `Authorization` header**; the catalogue is meant to be read. | Resource | Where | |---|---| | Base URL | `https://api.restrike.co/v1` | | OpenAPI 3.0 document | [api.restrike.co/openapi.json](https://api.restrike.co/openapi.json) | | Interactive reference | [docs.restrike.co/api/reference](https://docs.restrike.co/api/reference) | | Agent index | [restrike.co/llms.txt](https://restrike.co/llms.txt) | ## First requests Find a type by name or catalogue number: ```bash curl -s 'https://api.restrike.co/v1/types?q=krugerrand&pageSize=5' ``` Read one type in full, issues included: ```bash curl -s 'https://api.restrike.co/v1/types/south-africa/krugerrand/1-ounce' ``` Price its fine gold at spot, and convert: ```bash curl -s 'https://api.restrike.co/v1/spot' curl -s 'https://api.restrike.co/v1/rates' ``` Walk a country's coinage: ```bash curl -s 'https://api.restrike.co/v1/issuers/south-africa' curl -s 'https://api.restrike.co/v1/issuers/south-africa/series' curl -s 'https://api.restrike.co/v1/types?issuer=south-africa&sort=weight_desc&pageSize=50' ``` ## When to reach for this API It answers **structured questions about a specific gold coin**, which is a narrower job than it sounds and the one thing it does better than a search engine: * **Resolve a coin to its specification.** `GET /types?q=` does the lookup and gives you back fields, not prose: fine gold in grams, fineness, gross weight, diameter, thickness, years. * **Compare two coins on the same axes.** Every type is described to one specification. Two `GET /types/{issuer}/{series}/{type}` responses are directly comparable field by field with no translation step. * **Melt value.** `GET /spot` publishes the gold price this site prices with, per gram and per troy ounce; multiply a type's `fineWeight` by `pricePerGram`. `GET /rates` converts USD into another display currency off the same ECB table the pages use, so your numbers and ours agree. * **Read a year table.** A type response carries every issue: year, mint letter, finish, mintage, variety and marks. * **Enumerate a catalogue.** Issuer, then series, then types, paginated, and `GET /mints/{mint}` for everything one mint strikes. **Do not** reach for it to value a specific coin (numismatic premiums are not modelled), to grade or authenticate one, to look up anything about a *specific physical* coin (provenance, slab numbers), or to transact: nothing here buys or sells. ## Endpoints | Method | Path | What it returns | |---|---|---| | `GET` | `/issuers` | A page of issuing authorities (roots by default), with counts and a lead picture | | `GET` | `/issuers/highlighted` | The hand-picked row the home page leads with | | `GET` | `/issuers/{slug}` | One issuer, its sub-issuers and the shape of its catalogue | | `GET` | `/issuers/{issuerSlug}/series` | The series filed under an issuer's tree | | `GET` | `/issuers/{issuerSlug}/series/{seriesSlug}` | One series, with statistics | | `GET` | `/types` | A page of types; filter by issuer, series, mint or free text | | `GET` | `/types/{issuerSlug}/{seriesSlug}/{slug}` | One type: full specification, sides, pictures and issues | | `GET` | `/mints` | A page of mints | | `GET` | `/mints/{slug}` | One mint and the series it strikes | | `GET` | `/spot` | The gold spot price, USD per gram and per troy ounce | | `GET` | `/rates` | USD to display-currency conversion table | | `GET` | `/sitemap/types` | Every type's URL identity and last-modified date, 5,000 a page | | `GET` | `/sitemap/catalog` | Every root issuer, series and mint, as URL identities | The full request and response shapes for each are in the [interactive reference](https://docs.restrike.co/api/reference), generated from the same OpenAPI document the API serves. :::note The `/machines`, `/fractions` and `/wallet` groups belong to the pull machines. They appear in the OpenAPI document for completeness; `/wallet` answers `401` to anyone without a session. ::: # Versioning and deprecation The current version is **v1**, at `https://api.restrike.co/v1`. Build against the prefixed URL. The same paths also answer without the prefix (`https://api.restrike.co/types`) as a permanent alias for whatever the current version happens to be. That is convenient for a quick `curl` and wrong to pin an integration to, because it moves when the current version moves. ## Inside a version * Changes are **additive only**: new endpoints, new optional parameters, new fields on a response. * A field is never removed, renamed or retyped, and a code in `error` is never repurposed. * A breaking change ships as a **new prefix** (`/v2`), served alongside the old one. ## When a version winds down Every response the deprecated version serves carries: * `Deprecation: true` ([RFC 9745](https://www.rfc-editor.org/rfc/rfc9745.html)) * `Sunset: ` ([RFC 8594](https://www.rfc-editor.org/rfc/rfc8594.html)), the date after which it stops answering, never less than six months out * a `Link` header with `rel="successor-version"` pointing at the replacement `X-API-Version` names the serving version on every response, deprecated or not, so a client can assert it is talking to what it thinks it is. # Rate limits Public callers get **600 requests per 60 seconds**. Every response carries the budget so you can pace yourself rather than discover the ceiling: ``` RateLimit-Limit: 600 RateLimit-Remaining: 573 RateLimit-Reset: 41 RateLimit-Policy: 600;w=60;policy="public" ``` `RateLimit-Reset` is seconds until the window rolls. A refused request answers **429** with `Retry-After` set to the same number of seconds. The limit is enforced per IP address and is deliberately generous; if you need more for something interesting, write to [hello@restrike.co](mailto\:hello@restrike.co) rather than sharding across addresses. # Errors Every failure returns JSON in one shape: a rejected parameter, an unknown path, a fault on our side alike. There are no HTML error pages anywhere on the API. ```json { "error": "not_found", "message": "Brand not found.", "hint": "Check the slug against GET /brands.", "docs": "https://api.restrike.co/docs" } ``` `error` is the stable, machine-readable part and is safe to branch on: | Code | Meaning | |---|---| | `invalid_request` | A parameter or the path shape was rejected | | `unauthorized` | The endpoint needs a session you do not have | | `forbidden` | The session exists but may not do this | | `not_found` | The resource does not exist | | `rate_limited` | Over budget; see [rate limits](/api/rate-limits) | | `internal_error` | Our fault; safe to retry with backoff | `message` is prose and may be reworded. `hint` says what to change about the request. # Agent access Restrike treats machine readers as first-class. There are three routes in, and none of them involve parsing rendered HTML. ## The OpenAPI document as a tool set The OpenAPI document at [api.restrike.co/openapi.json](https://api.restrike.co/openapi.json) is written to be turned into tools without a human naming each one: * Every operation has a **unique `operationId`** (`getType`, `listTypes`, `getGoldSpot`) usable directly as a function name. * Every operation has a **description** saying what it returns and when to reach for it. * Every parameter and every response is **typed**, including the error bodies. * `servers`, `contact`, `license` and `externalDocs` are all populated, so a generator has somewhere to point. Point your tool generator at it and it should need no hand editing. ## Markdown instead of HTML on restrike.co Every public page on `restrike.co` is also served as markdown, following the [acceptmarkdown.com](https://acceptmarkdown.com) convention. Ask for it: ```bash curl -s -H 'Accept: text/markdown' https://restrike.co/coins/south-africa/krugerrand/1-ounce ``` You get `Content-Type: text/markdown; charset=utf-8` and `Vary: Accept`. A client that asks for a media type the site cannot produce gets a `406` naming what is available, rather than an HTML page it then has to strip. A type page that renders as tens of kilobytes of HTML is about a kilobyte as markdown, issues table included; this is the intended route for anything reading the site rather than the API. The index of everything readable this way is at [restrike.co/llms.txt](https://restrike.co/llms.txt). ## This site is readable the same way The documentation you are reading follows the same rule: * [docs.restrike.co/llms.txt](https://docs.restrike.co/llms.txt) is a concise index of every page here. * [docs.restrike.co/llms-full.txt](https://docs.restrike.co/llms-full.txt) is the whole site's content in one file. * Every page is also available as plain markdown under `/assets/md/`, mirroring the page path: for example `/assets/md/api/quickstart.md`. The "Copy page for AI" control on each page hands out the same file. # Terms of use The API is free to read and free to build on, within the [rate limits](/api/rate-limits). Two conditions: * **Do not present the catalogue as your own.** Attribute it, with a link to the type page you took the data from. * **Do not hotlink the images.** They are served from our CDN and paid for by us; copy what you need instead. The Numista identifiers carried on types are references to Numista's catalogue, not a licence to its data; Numista's own terms apply to anything you fetch from Numista. Melt values are fine gold at spot and nothing more: not a quote, not a valuation, and not to be presented as either. Questions: [hello@restrike.co](mailto\:hello@restrike.co). # Restrike API Version: `1.0.0` A read-only reference for gold coins: the catalogue (issuers, series, types, issues, mints), in Numista's vocabulary, with the gold price the melt values rest on. ## When to use this API Reach for it when you need **structured facts about a specific coin** rather than prose about gold in general: - Resolve a coin to its type (`GET /types?q=Krugerrand`) and read back its fine weight, fineness, diameter, years and issues as fields rather than sentences. - Compare two coins on the same axes. Every type in the catalogue is described to one specification, which is the point of it; two `GET /types/{issuerSlug}/{seriesSlug}/{slug}` calls are directly comparable field by field. - Put a melt value on a coin: `GET /spot` gives USD per gram of fine gold, and `GET /rates` converts it into another display currency off the same ECB table. - Find what a mint has struck (`GET /mints/{slug}`) and every type carrying its letter. - Enumerate an issuer's catalogue: `GET /issuers/{slug}`, then `GET /issuers/{issuerSlug}/series`, then `GET /types?issuer=...`. It is **not** the right tool for valuations beyond melt, for authentication advice, for anything about a specific physical coin (a grade, a slab, a provenance), or for placing an order: nothing here transacts. ## Access The catalogue, spot and rates endpoints are public: no key, no account, no `Authorization` header. The `/wallet` group belongs to a signed-in player: it needs a session cookie of any role, and answers 401 without one. ## Versioning and deprecation The current version is **v1**, served at `https://api.restrike.co/v1`. Build against the prefixed URL. The same paths answer without the prefix as a permanent alias for whatever the current version is: handy for a quick curl, wrong to pin an integration to. Inside a version, changes are additive only: new endpoints, new optional parameters, new response fields. A field is never removed, renamed or retyped, and a code in `error` is never repurposed. A breaking change ships as a new prefix (`/v2`) served alongside the old one. When a version begins winding down, every response from it carries `Deprecation: true` (RFC 9745) and `Sunset: ` (RFC 8594); the date it stops answering, never less than six months out, plus a `Link` header with `rel="successor-version"`. `X-API-Version` names the serving version on every response. ## Rate limits Public callers get 600 requests per 60 seconds. Every response carries `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` (seconds until the window rolls) and `RateLimit-Policy`, so a client can pace itself instead of discovering the ceiling. A refused request answers **429** with `Retry-After`. ## Errors Every failure (a bad parameter, an unknown path, a fault on our side) returns JSON with the same fields: `error` (a stable machine-readable code), `message` (prose), `hint` (what to change) and `docs` (where to read more). Codes: `invalid_request`, `unauthorized`, `forbidden`, `not_found`, `rate_limited`, `internal_error`. ## Servers - `https://api.restrike.co/v1`: Version 1; pin to this. - `https://api.restrike.co`: Unversioned alias for the current version. Convenient, not stable. ## Endpoints ### Issuers Issuing authorities, as Numista's tree, and the series filed under them. - [`GET /issuers`](/api/reference/issuers#listissuers): List issuers - [`GET /issuers/highlighted`](/api/reference/issuers#listhighlightedissuers): List the highlighted issuers - [`GET /issuers/{slug}`](/api/reference/issuers#getissuer): Get an issuer by slug - [`GET /issuers/{issuerSlug}/series`](/api/reference/issuers#listissuerseries): List an issuer's series - [`GET /issuers/{issuerSlug}/series/{seriesSlug}`](/api/reference/issuers#getseries): Get a series by root issuer + series slug ### Types The unit of the catalogue: one design at one denomination and composition, with its issues. - [`GET /types`](/api/reference/types#listtypes): List coin types - [`GET /types/{issuerSlug}/{seriesSlug}/{slug}`](/api/reference/types#gettype): Get a type (full record) by root issuer + series + slug ### Mints Who struck the coins, and the series they strike. - [`GET /mints`](/api/reference/mints#listmints): List mints - [`GET /mints/{slug}`](/api/reference/mints#getmint): Get a mint by slug ### Spot The gold price melt values are computed from. - [`GET /spot`](/api/reference/spot#getgoldspot): The gold spot price in USD ### Rates The USD conversion table melt values are rendered with. - [`GET /rates`](/api/reference/rates#getexchangerates): USD → display-currency conversion rates ### Fractions Metadata for the tokenised coins. Everything about value lives on chain; this only says what a token id means. - [`GET /fractions/{file}`](/api/reference/fractions#getfractionmetadata): ERC-1155 metadata for one pool entry - [`GET /machines`](/api/reference/fractions#getmachines): The pull machines, their odds and their pools ### Wallet The signed-in player's embedded wallet. Holds no key and moves no money: signing happens in the browser, against Openfort. - [`GET /wallet`](/api/reference/wallet#getwallet): The signed-in player's embedded wallet - [`POST /wallet`](/api/reference/wallet#linkwallet): Record the player's wallet address - [`POST /wallet/encryption-session`](/api/reference/wallet#createwalletencryptionsession): Authorise this browser to open the player's wallet - [`GET /wallet/pulls`](/api/reference/wallet#getwalletpulls): Every pull the signed-in player has made - [`GET /wallet/holdings`](/api/reference/wallet#getwalletholdings): The watches the signed-in player holds a share of ### Sitemap Bulk, cheap enumeration of every catalogue entity that has a page: identity and last-modified date only. - [`GET /sitemap/types`](/api/reference/sitemap#listsitemaptypes): Every type's URL identity and last-modified date - [`GET /sitemap/catalog`](/api/reference/sitemap#listsitemapcatalog): Every root issuer, series and mint, as URL identities # Fractions Metadata for the tokenised coins. Everything about value lives on chain; this only says what a token id means. ## ERC-1155 metadata for one pool entry `GET /fractions/{file}` What a wallet or marketplace fetches to render a token. The token id is assigned in the pool table and used verbatim on chain, so this is the only place that knows token 7 means a particular type in a particular condition. The chain owns everything about value; nothing here is a price. ### Path parameters - `file` `string` _(required)_ ### Responses #### `200`: Metadata for the token. Body (`application/json`): - `name` `string` _(required)_ - `description` `string` _(required)_ - `image` `string | null` _(required)_: Our own background-removed crop of the obverse, served from the Restrike CDN. Null when the pipeline has not produced one; never a source URL. - `external_url` `string` _(required)_ - `attributes` `object[]` _(required)_ - `trait_type` `string` _(required)_ - `value` `string | number` _(required)_ #### `404`: No pool entry carries that token id. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/fractions/7.json ``` ```ts fetch('https://api.restrike.co/v1/fractions/7.json') ``` ## The pull machines, their odds and their pools `GET /machines` Everything needed to render the gacha, read from the chain rather than mirrored: tier prices, the published odds table, and each machine's pool with live house prices and exposure. Catalogue names and images are joined in from the pool mapping. ### Responses #### `200`: The current machine configuration. Body (`application/json`): - `address` `string` _(required)_ - `chainId` `integer` _(required)_ - `oddsVersion` `integer` _(required)_ - `odds` `object[]` _(required)_ - `label` `string` _(required)_ - `chanceBps` `integer` _(required)_: Probability of this band, in basis points. - `minMultiplierBps` `integer` _(required)_ - `maxMultiplierBps` `integer` _(required)_ - `expectedValueBps` `integer` _(required)_: Expected return of a pull, in basis points of its price, at house prices. 9930 means 0.993x. Not what a pull is worth in cash: selling back takes the buyback haircut. - `machines` `object[]` _(required)_ - `tier` `integer` _(required)_ - `price` `string` _(required)_: USDC base units, decimal string. - `open` `boolean` _(required)_: A machine with no price or an empty pool cannot be pulled. - `pool` `object[]` _(required)_ - `tokenId` `integer` _(required)_ - `name` `string | null` _(required)_: Root issuer and type title, from the catalogue: "South Africa 1 Ounce Krugerrand". Null when no pool mapping exists for this token id yet. - `issuer` `string | null` _(required)_ - `series` `string | null` _(required)_ - `fineWeight` `number | null` _(required)_ - `condition` `string | null` _(required)_ - `image` `string | null` _(required)_ - `housePrice` `string` _(required)_: USDC base units, as a decimal string. Six decimals, so 20000000 is 20 USDC. - `priceUpdatedAt` `integer` _(required)_: Unix seconds. - `stale` `boolean` _(required)_: True once the price is too old to pull against, at which point pulls refund. - `outstandingPpm` `integer` _(required)_ - `maxOutstandingPpm` `integer` _(required)_ - `buybackBps` `integer` _(required)_ #### `503`: No chain configuration, so nothing can be read. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/machines ``` ```ts fetch('https://api.restrike.co/v1/machines') ``` # Issuers Issuing authorities, as Numista's tree, and the series filed under them. ## List issuers `GET /issuers` A page of issuing authorities, each with its series and type counts (its whole subtree) and one representative picture. Root issuers by default; `roots=false` lists every node of the tree. Filter with `q`, order by name or catalogue depth with `sort`. ### Query parameters - `page` `integer` - `pageSize` `integer` - `q` `string` - `roots` `string`: Only root issuers (default), or every node of the tree. - `sort` `string` ### Responses #### `200`: A page of issuers. Body (`application/json`): - `data` `object & object[]` _(required)_ - `page` `integer` _(required)_ - `pageSize` `integer` _(required)_ - `total` `integer` _(required)_ - `totalPages` `integer` _(required)_ ### Example request ```bash curl 'https://api.restrike.co/v1/issuers?page=1&pageSize=24&q=string&roots=true&sort=name_asc' ``` ```ts fetch('https://api.restrike.co/v1/issuers?page=1&pageSize=24&q=string&roots=true&sort=name_asc') ``` ## List the highlighted issuers `GET /issuers/highlighted` The issuers the home page leads with, in editorial order. A fixed, hand-picked row rather than a ranking, so it does not reshuffle when the catalogue grows. ### Responses #### `200`: The highlighted issuers, in editorial order. Body (`application/json`): - `data` `object & object[]` _(required)_ ### Example request ```bash curl https://api.restrike.co/v1/issuers/highlighted ``` ```ts fetch('https://api.restrike.co/v1/issuers/highlighted') ``` ## Get an issuer by slug `GET /issuers/{slug}` One issuer by its URL slug (`south-africa`, `germany`). Slugs are stable and are what every other issuer-scoped path takes. Includes its children in the tree and `stats`, the shape of everything filed beneath it: year and size ranges, fine gold per coin, finenesses, weight classes and mints. ### Path parameters - `slug` `string` _(required)_ ### Responses #### `200`: The issuer. #### `404`: Not found. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/issuers/south-africa ``` ```ts fetch('https://api.restrike.co/v1/issuers/south-africa') ``` ## List an issuer's series `GET /issuers/{issuerSlug}/series` The series (programmes and type families: Krugerrand, Sovereign, 20 Mark) filed under one root issuer or any issuer beneath it, each with its type count and a lead type to illustrate it. ### Path parameters - `issuerSlug` `string` _(required)_ ### Query parameters - `page` `integer` - `pageSize` `integer` - `q` `string` ### Responses #### `200`: A page of series. Body (`application/json`): - `data` `object & object[]` _(required)_ - `page` `integer` _(required)_ - `pageSize` `integer` _(required)_ - `total` `integer` _(required)_ - `totalPages` `integer` _(required)_ #### `404`: Issuer not found. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl 'https://api.restrike.co/v1/issuers/south-africa/series?page=1&pageSize=24&q=string' ``` ```ts fetch('https://api.restrike.co/v1/issuers/south-africa/series?page=1&pageSize=24&q=string') ``` ## Get a series by root issuer + series slug `GET /issuers/{issuerSlug}/series/{seriesSlug}` One series, addressed by its root issuer and its own slug. Includes the leaf issuer it is filed under, the mint that strikes it, a lead type, and `stats` derived from the series' own types. ### Path parameters - `issuerSlug` `string` _(required)_ - `seriesSlug` `string` _(required)_ ### Responses #### `200`: The series. #### `404`: Not found. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/issuers/south-africa/series/krugerrand ``` ```ts fetch('https://api.restrike.co/v1/issuers/south-africa/series/krugerrand') ``` # Mints Who struck the coins, and the series they strike. ## List mints `GET /mints` A page of mints, each with how many series it strikes and how many issues carry its letter, and one representative picture. The mint is how dealers organise their catalogues, so it has pages of its own. ### Query parameters - `page` `integer` - `pageSize` `integer` - `q` `string` ### Responses #### `200`: A page of mints. Body (`application/json`): - `data` `object & object[]` _(required)_ - `page` `integer` _(required)_ - `pageSize` `integer` _(required)_ - `total` `integer` _(required)_ - `totalPages` `integer` _(required)_ ### Example request ```bash curl 'https://api.restrike.co/v1/mints?page=1&pageSize=24&q=string' ``` ```ts fetch('https://api.restrike.co/v1/mints?page=1&pageSize=24&q=string') ``` ## Get a mint by slug `GET /mints/{slug}` One mint by its URL slug (`perth-mint`, `royal-mint`): the series it strikes, each with a lead type, and `stats` over every type it has struck, whether as a series' mint or through an issue carrying its letter. ### Path parameters - `slug` `string` _(required)_ ### Responses #### `200`: The mint. #### `404`: Not found. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/mints/south-africa ``` ```ts fetch('https://api.restrike.co/v1/mints/south-africa') ``` # Rates The USD conversion table melt values are rendered with. ## USD → display-currency conversion rates `GET /rates` The conversion table listing prices are rendered with: units of each supported display currency per 1 USD, from the ECB reference rates. Published so a caller can convert the same way this API does. ### Responses #### `200`: Units per 1 USD for each display currency (ECB reference rates). Body (`application/json`): - `base` `string` _(required)_ - `rates` `object` _(required)_: Units per 1 USD, keyed by display currency. May be empty when no rate table is available; clients then fall back to USD. ### Example request ```bash curl https://api.restrike.co/v1/rates ``` ```ts fetch('https://api.restrike.co/v1/rates') ``` # Sitemap Bulk, cheap enumeration of every catalogue entity that has a page: identity and last-modified date only. ## Every type's URL identity and last-modified date `GET /sitemap/types` Bulk enumeration for building a sitemap or an incremental mirror: root issuer slug, series slug, type slug and the date the type last changed, up to 10,000 rows a page. Ordered by id so paging stays stable while the catalogue is being written to. ### Query parameters - `page` `integer` - `pageSize` `integer` ### Responses #### `200`: A page of type identities. Body (`application/json`): - `data` `object[]` _(required)_ - `issuerSlug` `string` _(required)_: The ROOT issuer's slug, the URL's first segment. - `seriesSlug` `string` _(required)_ - `slug` `string` _(required)_ - `updatedAt` `string` _(required)_: ISO date (YYYY-MM-DD). - `page` `integer` _(required)_ - `pageSize` `integer` _(required)_ - `total` `integer` _(required)_ - `totalPages` `integer` _(required)_ ### Example request ```bash curl 'https://api.restrike.co/v1/sitemap/types?page=1&pageSize=5000' ``` ```ts fetch('https://api.restrike.co/v1/sitemap/types?page=1&pageSize=5000') ``` ## Every root issuer, series and mint, as URL identities `GET /sitemap/catalog` The small layers above types, unpaginated because there are hundreds rather than thousands of them. Issuers are the roots only: only roots have pages. ### Responses #### `200`: Every root issuer, every series and every mint. Body (`application/json`): - `issuers` `object[]` _(required)_ - `slug` `string` _(required)_ - `updatedAt` `string` _(required)_ - `series` `object[]` _(required)_ - `issuerSlug` `string` _(required)_ - `slug` `string` _(required)_ - `updatedAt` `string` _(required)_ - `mints` `object[]` _(required)_ - `slug` `string` _(required)_ - `updatedAt` `string` _(required)_ ### Example request ```bash curl https://api.restrike.co/v1/sitemap/catalog ``` ```ts fetch('https://api.restrike.co/v1/sitemap/catalog') ``` # Spot The gold price melt values are computed from. ## The gold spot price in USD `GET /spot` USD per troy ounce and per gram of fine gold, from the feed this API prices melt value with. Multiply a type's `fineWeight` (grams) by `pricePerGram` to get the melt value the type pages show; `GET /rates` converts it into another display currency. ### Responses #### `200`: The current gold spot price. Body (`application/json`): - `metal` `string` _(required)_ - `currency` `string` _(required)_ - `pricePerOunce` `number` _(required)_: USD per troy ounce of fine gold. - `pricePerGram` `number` _(required)_: USD per gram of fine gold. - `asOf` `string` _(required)_: When the feed set this price, ISO 8601. #### `503`: No price is available: the feed is unreachable and nothing is cached yet. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/spot ``` ```ts fetch('https://api.restrike.co/v1/spot') ``` # Types The unit of the catalogue: one design at one denomination and composition, with its issues. ## List coin types `GET /types` A page of types, the catalogue's unit of description: one design at one denomination and composition, with its fine gold weight, fineness and years. Filter by root issuer, series, mint or free text; sort by title, newest, weight or first year. ### Query parameters - `page` `integer` - `pageSize` `integer` - `q` `string` - `id` `string`: Exact type id - `issuer` `string`: Root issuer slug - `series` `string`: Series slug - `mint` `string`: Mint slug: the series' mint or an issue's - `sort` `string` ### Responses #### `200`: A page of types. Body (`application/json`): - `data` `object | null[]` _(required)_ - `id` `string` _(required)_ - `title` `string` _(required)_ - `slug` `string` _(required)_ - `category` `string` _(required)_ - `fineWeight` `number` _(required)_ - `fineness` `number` _(required)_ - `weight` `number` _(required)_ - `minYear` `integer | null` _(required)_ - `maxYear` `integer | null` _(required)_ - `thumbnailUrl` `string | null` _(required)_ - `thumbnailIsCropped` `boolean` _(required)_ - `issuer` `object` _(required)_ - `id` `string` _(required)_ - `name` `string` _(required)_ - `slug` `string` _(required)_ - `rootIssuer` `object` _(required)_ - `id` `string` _(required)_ - `name` `string` _(required)_ - `slug` `string` _(required)_ - `series` `object` _(required)_ - `id` `string` _(required)_ - `name` `string` _(required)_ - `slug` `string` _(required)_ - `page` `integer` _(required)_ - `pageSize` `integer` _(required)_ - `total` `integer` _(required)_ - `totalPages` `integer` _(required)_ ### Example request ```bash curl 'https://api.restrike.co/v1/types?page=1&pageSize=24&q=string&id=string&issuer=string&series=string&mint=string&sort=newest' ``` ```ts fetch('https://api.restrike.co/v1/types?page=1&pageSize=24&q=string&id=string&issuer=string&series=string&mint=string&sort=newest') ``` ## Get a type (full record) by root issuer + series + slug `GET /types/{issuerSlug}/{seriesSlug}/{slug}` One type in full: Numista's feature set (value, composition, weight, size, thickness, shape, technique, orientation, references), its obverse, reverse and edge, its pictures with attribution, and every issue by year, mint letter and finish. ### Path parameters - `issuerSlug` `string` _(required)_ - `seriesSlug` `string` _(required)_ - `slug` `string` _(required)_ ### Responses #### `200`: The type. Body (`application/json`): - `id` `string` _(required)_ - `title` `string` _(required)_ - `slug` `string` _(required)_ - `numistaId` `integer | null` _(required)_ - `updatedAt` `string` _(required)_ - `category` `string` _(required)_ - `ruler` `string | null` _(required)_ - `minYear` `integer | null` _(required)_ - `maxYear` `integer | null` _(required)_ - `value` `string | null` _(required)_ - `valueNumeric` `number | null` _(required)_ - `currency` `string | null` _(required)_ - `composition` `string` _(required)_ - `fineness` `number` _(required)_ - `weight` `number` _(required)_ - `fineWeight` `number` _(required)_ - `size` `number | null` _(required)_ - `thickness` `number | null` _(required)_ - `shape` `string` _(required)_ - `technique` `string` _(required)_ - `orientation` `string | null` _(required)_ - `references` `string[]` _(required)_ - `tags` `string[]` _(required)_ - `commemoratedTopic` `string | null` _(required)_ - `comments` `string | null` _(required)_ - `demonetized` `boolean` _(required)_ - `legalTender` `boolean` _(required)_ - `issuer` `object` _(required)_ - `id` `string` _(required)_ - `name` `string` _(required)_ - `slug` `string` _(required)_ - `rootIssuer` `object` _(required)_ - `id` `string` _(required)_ - `name` `string` _(required)_ - `slug` `string` _(required)_ - `series` `object` _(required)_ - `id` `string` _(required)_ - `name` `string` _(required)_ - `slug` `string` _(required)_ - `mint` `object | null` _(required)_ - `id` `string` _(required)_ - `name` `string` _(required)_ - `slug` `string` _(required)_ - `letter` `string | null` _(required)_ - `sides` `object[]` _(required)_ - `side` `string` _(required)_ - `description` `string | null` _(required)_ - `lettering` `string | null` _(required)_ - `unabridgedLegend` `string | null` _(required)_ - `letteringTranslation` `string | null` _(required)_ - `engravers` `string[]` _(required)_ - `pictures` `object[]` _(required)_ - `id` `string` _(required)_ - `url` `string` _(required)_ - `side` `string` _(required)_ - `copyright` `string | null` _(required)_ - `copyrightUrl` `string | null` _(required)_ - `license` `string | null` _(required)_ - `issues` `object[]` _(required)_ - `id` `string` _(required)_ - `isDated` `boolean` _(required)_ - `year` `integer | null` _(required)_ - `gregorianYear` `integer | null` _(required)_ - `minYear` `integer | null` _(required)_ - `maxYear` `integer | null` _(required)_ - `mintLetter` `string` _(required)_ - `mint` `object | null` _(required)_ - `id` `string` _(required)_ - `name` `string` _(required)_ - `slug` `string` _(required)_ - `letter` `string | null` _(required)_ - `marks` `string[]` _(required)_ - `finish` `string` _(required)_ - `variety` `string` _(required)_ - `mintage` `integer | null` _(required)_ - `references` `string[]` _(required)_ - `comment` `string | null` _(required)_ #### `404`: Not found. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/types/south-africa/krugerrand/1-ounce ``` ```ts fetch('https://api.restrike.co/v1/types/south-africa/krugerrand/1-ounce') ``` # Wallet The signed-in player's embedded wallet. Holds no key and moves no money: signing happens in the browser, against Openfort. ## The signed-in player's embedded wallet `GET /wallet` The wallet Openfort holds for the signed-in account: its address, its chain, and whether it has been delegated to the account implementation via EIP-7702 yet. Answers `{ wallet: null }` for an account that has never played, which is the normal state. ### Responses #### `200`: The wallet, or null when the account has none yet. Body (`application/json`): - `wallet` `object | null` _(required)_: Null when the signed-in account has no wallet yet, which is the normal state until somebody chooses to play. - `address` `string` _(required)_: EIP-55 checksummed address of the player's embedded wallet. - `chainId` `integer` _(required)_: The chain the wallet was created for. Base is 8453. - `delegated` `boolean` _(required)_: Whether the EIP-7702 authorization has landed, delegating the address to the account implementation. False means the app should still ask for that signature; it is only ever asked once. #### `401`: No session. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. #### `503`: No Openfort configuration, so no wallet can exist on this deployment. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/wallet ``` ```ts fetch('https://api.restrike.co/v1/wallet') ``` ## Record the player's wallet address `POST /wallet` Takes the embedded wallet the browser created, upgrades it to an EIP-7702 Delegated Account if it is not one already, and caches the address so holdings render from the catalogue database without a round trip. Accepts no input: the identity comes from the session, never from the caller. Answers 404 until the browser has made the wallet, which is the signal to make it. Idempotent. ### Responses #### `200`: The recorded wallet. Body (`application/json`): - `wallet` `object | null` _(required)_: Null when the signed-in account has no wallet yet, which is the normal state until somebody chooses to play. - `address` `string` _(required)_: EIP-55 checksummed address of the player's embedded wallet. - `chainId` `integer` _(required)_: The chain the wallet was created for. Base is 8453. - `delegated` `boolean` _(required)_: Whether the EIP-7702 authorization has landed, delegating the address to the account implementation. False means the app should still ask for that signature; it is only ever asked once. #### `401`: No session. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. #### `404`: The browser has not created the wallet yet. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. #### `503`: Openfort is not configured on this deployment. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/wallet \ --request POST ``` ```ts fetch('https://api.restrike.co/v1/wallet', { method: 'POST' }) ``` ## Authorise this browser to open the player's wallet `POST /wallet/encryption-session` Mints a short-lived Openfort encryption session so the signed-in player's browser can decrypt its own recovery share. Recovery is automatic, so the share is encrypted with project entropy that only this API holds; the session is the narrow, expiring authorisation to use it once. It confers nothing else and cannot sign. ### Responses #### `200`: The encryption session id. Body (`application/json`): - `session` `string` _(required)_: The encryption session id, passed straight to the Openfort SDK. #### `401`: No session. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. #### `503`: Openfort or Shield is not configured on this deployment. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/wallet/encryption-session \ --request POST ``` ```ts fetch('https://api.restrike.co/v1/wallet/encryption-session', { method: 'POST' }) ``` ## Every pull the signed-in player has made `GET /wallet/pulls` The player's pulls on the Fractions machine, newest first, read from the chain rather than mirrored: the PullOpened and PullSettled logs for their wallet, and each pull's current state. A settled pull carries its multiplier, its value at house prices and the watch shares it produced, with names and images joined in from the catalogue. Empty for an account with no wallet yet. ### Responses #### `200`: The player's pulls. Body (`application/json`): - `address` `string | null` _(required)_: The player's wallet. Null when the account has none yet, in which case the list is empty. - `machine` `string` _(required)_ - `chainId` `integer` _(required)_ - `pulls` `object[]` _(required)_: Newest first. - `requestId` `string` _(required)_: The Chainlink VRF request id that identifies the pull on chain, as a decimal string. - `tier` `integer` _(required)_ - `price` `string` _(required)_: What the pull cost, in USDC base units. - `openedAt` `integer` _(required)_: Unix seconds. - `txHash` `string` _(required)_: The transaction that opened the pull. - `state` `string` _(required)_: open: waiting for the randomness. settled: decided, prizes below. refundable: the stake can be returned (settlement failed, or the oracle never answered). refunded: the stake was returned. - `settlement` `object | null` _(required)_ - `multiplierBps` `integer` _(required)_: What the roll produced, in basis points of the price. 10000 is 1.00x. - `value` `string` _(required)_: The prize's value at house prices, USDC base units. - `txHash` `string` _(required)_: The transaction that settled the pull. - `prizes` `object[]` _(required)_ - `tokenId` `integer` _(required)_ - `ppm` `integer` _(required)_: Millionths of one coin's worth. 1000000 is a whole coin. - `name` `string | null` _(required)_: Root issuer and type title, from the catalogue: "South Africa 1 Ounce Krugerrand". Null when no pool mapping exists for this token id yet. - `issuer` `string | null` _(required)_ - `series` `string | null` _(required)_ - `fineWeight` `number | null` _(required)_ - `condition` `string | null` _(required)_ - `image` `string | null` _(required)_ #### `401`: No session. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. #### `503`: No chain configuration, so nothing can be read. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/wallet/pulls ``` ```ts fetch('https://api.restrike.co/v1/wallet/pulls') ``` ## The watches the signed-in player holds a share of `GET /wallet/holdings` Every pool watch the player has a stake in, read from the chain: what the machine still owes them from settled pulls, what has already been minted to their wallet, and what the trade desk would pay for the two together right now. Also whether the desk is open at all and whether it is already approved to take their fractions, which is what the app needs to make a sale one signature. Empty for an account with no wallet yet. ### Responses #### `200`: The player's holdings and the desk's terms. Body (`application/json`): - `address` `string | null` _(required)_ - `chainId` `integer` _(required)_ - `machine` `string` _(required)_ - `fractions` `string` _(required)_ - `desk` `string` _(required)_ - `deskOpen` `boolean` _(required)_: False while the desk is paused or its reserve is empty. - `reserve` `string` _(required)_: USDC the desk can pay out of, base units. - `deskApproved` `boolean` _(required)_: Whether the desk is already an approved operator on the player's fractions. False means a sale has to approve it first, which the app batches in. - `holdings` `object[]` _(required)_ - `tokenId` `integer` _(required)_ - `name` `string | null` _(required)_: Root issuer and type title, from the catalogue: "South Africa 1 Ounce Krugerrand". Null when no pool mapping exists for this token id yet. - `issuer` `string | null` _(required)_ - `series` `string | null` _(required)_ - `fineWeight` `number | null` _(required)_ - `condition` `string | null` _(required)_ - `image` `string | null` _(required)_ - `owedPpm` `integer` _(required)_: Won but not yet minted. Claiming mints it; selling claims first. - `balancePpm` `integer` _(required)_: Minted, in the wallet. - `housePrice` `string` _(required)_: USDC base units. - `bidBps` `integer` _(required)_: What the desk pays, in basis points of the house price. - `stale` `boolean` _(required)_ - `quote` `string | null` _(required)_: What the desk pays for the whole holding right now, USDC base units. Null when it will not quote: the price is stale or the entry is unlisted. #### `401`: No session. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. #### `503`: No chain configuration, so nothing can be read. Body (`application/json`): - `error` `string` _(required)_: Stable machine-readable error code. - `message` `string`: Human-readable explanation of what went wrong. - `hint` `string`: What to change about the request to make it succeed. - `docs` `string`: Documentation covering this endpoint. ### Example request ```bash curl https://api.restrike.co/v1/wallet/holdings ``` ```ts fetch('https://api.restrike.co/v1/wallet/holdings') ```