# Magic: The Gathering Card Database & Pricing API - Scryfall (`jungle_synthesizer/scryfall-mtg-cards-api-wrapper`) Actor

Magic: The Gathering card database with search, name/ID lookup, set walks, and bulk corpus dumps via Scryfall. Returns mana cost, oracle text, format legality (Standard/Modern/Commander/etc), and USD/EUR/TIX prices, plus TCGPlayer and Cardmarket IDs for joins.

- **URL**: https://apify.com/jungle\_synthesizer/scryfall-mtg-cards-api-wrapper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** E-commerce, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 record scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Magic: The Gathering Card Database & Pricing API — Scryfall

Pull structured Magic: The Gathering card data from [Scryfall](https://scryfall.com), the card
database every serious MTG deck-builder already relies on. Search by query syntax, look up cards
by name or ID, walk an entire set, or pull a full corpus dump — all six modes return the same
clean row: mana cost, oracle text, format legality across 20+ formats, and USD/EUR/TIX prices.

***

### Scryfall MTG Cards Scraper Features

- Searches with full Scryfall query syntax — `c:r t:creature cmc:3 f:standard` and friends
- Looks up cards by exact name, fuzzy name, or Scryfall ID, and skips a bad entry in a batch instead of failing the whole run
- Walks every printing in a set by three-letter code
- Pulls the full card corpus via a bulk dump — oracle text only, full reprint history, or every language and variant
- Returns format legality for Standard, Modern, Commander, Pioneer, Pauper, Legacy, Vintage, and 15 more formats in one field
- Includes USD, USD foil, EUR, and MTGO (tix) prices, plus TCGPlayer, Cardmarket, MTGO, and Arena IDs for joining against other data sources

***

### Who Uses Magic: The Gathering Card Data?

- **Deck-building tool developers** — power a card search box or price tracker without maintaining your own card corpus
- **Collectors and sellers** — cross-reference TCGPlayer and Cardmarket IDs to compare prices across marketplaces, or track a want-list's value over time
- **Content creators and set reviewers** — walk a new set the day it's indexed and pull every card's text and art in one pass
- **Format and metagame analysts** — filter by format legality to build Standard or Commander card pools, which is the tedious part nobody enjoys doing by hand
- **Data engineers** — bulk-ingest the whole catalogue (or just Oracle text) as a seed table for a larger MTG dataset

***

### How Scryfall MTG Cards Scraper Works

1. Pick a mode — Search Query, By Name, By Scryfall ID, Walk a Set, Bulk Dump, or Random Card.
2. Give it the matching input: a query string, a list of names or IDs, a set code, or a bulk dump type. Everything else is optional.
3. The scraper paginates or streams through the results and stops once it reaches your `Max Items` cap, so a five-card test run and a full-set walk cost exactly what they should.
4. You get back one flat row per card printing — same field set regardless of which mode you ran.

***

### Input

```json
{
  "mode": "search",
  "query": "t:creature f:standard",
  "maxItems": 50
}
```

| Field           | Type    | Default        | Description |
|-----------------|---------|----------------|-------------|
| `mode`          | String  | `search`       | `search`, `by_name`, `by_id`, `set_walk`, `bulk`, or `random` |
| `query`         | String  | `t:creature`   | Scryfall query syntax. Required when `mode` is Search Query |
| `cardNames`     | Array   | —              | Card names to look up. Required when `mode` is By Name |
| `fuzzyName`     | Boolean | `false`        | When `mode` is By Name, match loosely instead of requiring the exact name |
| `cardIds`       | Array   | —              | Scryfall card IDs to fetch. Required when `mode` is By Scryfall ID |
| `setCode`       | String  | —              | Three-letter set code (`eld`, `znr`). Required when `mode` is Walk a Set |
| `bulkType`      | String  | `oracle_cards` | `oracle_cards`, `unique_artwork`, `default_cards`, or `all_cards`. Used when `mode` is Bulk Dump |
| `includePrices` | Boolean | `true`         | Include USD/EUR/TIX prices in the output |
| `maxItems`      | Integer | `15`           | Maximum cards to return. `0` = unlimited (Random Card mode caps at 50 regardless) |

#### By name, skipping a miss

```json
{
  "mode": "by_name",
  "cardNames": ["Llanowar Elves", "Lightning Bolt", "Not A Real Card"],
  "fuzzyName": false
}
```

A name that doesn't resolve is logged and skipped — the other two still come back.

#### Walking a whole set

```json
{
  "mode": "set_walk",
  "setCode": "eld",
  "maxItems": 0
}
```

#### Bulk corpus dump

```json
{
  "mode": "bulk",
  "bulkType": "oracle_cards",
  "maxItems": 0
}
```

***

### Scryfall MTG Cards Scraper Output Fields

Every mode returns the same row shape — one object per card printing.

```json
{
  "id": "6a0b230b-d391-4998-a3f7-7b158a0ec2cd",
  "oracle_id": "68954295-54e3-4303-a6bc-fc4547a4e3a3",
  "name": "Llanowar Elves",
  "lang": "en",
  "released_at": "2024-11-15",
  "mana_cost": "{G}",
  "cmc": 1,
  "type_line": "Creature — Elf Druid",
  "oracle_text": "{T}: Add {G}.",
  "power": "1",
  "toughness": "1",
  "colors": ["G"],
  "legalities": { "standard": "legal", "modern": "legal", "commander": "legal", "pauper": "legal" },
  "set": "fdn",
  "set_name": "Foundations",
  "collector_number": "227",
  "rarity": "common",
  "artist": "Larry MacDougall",
  "prices": { "usd": "0.15", "usd_foil": "0.49", "eur": "0.13", "tix": "0.02" },
  "tcgplayer_id": 557921,
  "cardmarket_id": 795132,
  "scryfall_uri": "https://scryfall.com/card/fdn/227/llanowar-elves"
}
```

| Field                                                     | Type   | Description |
|-----------------------------------------------------------|--------|-------------|
| `id`                                                      | String | Scryfall card ID (unique per printing) |
| `oracle_id`                                               | String | Scryfall oracle ID (stable across every reprint of this card) |
| `name`                                                    | String | Card name |
| `lang`                                                    | String | Language code |
| `released_at`                                             | String | Release date of this printing |
| `layout`                                                  | String | Card layout (`normal`, `transform`, `split`, …) |
| `mana_cost`                                               | String | Mana cost string |
| `cmc`                                                     | Number | Converted mana cost / mana value |
| `type_line`                                               | String | Full type line |
| `oracle_text`                                             | String | Rules text |
| `power` / `toughness` / `loyalty`                         | String | Creature or planeswalker stats where applicable |
| `colors` / `color_identity`                               | Array  | Card colors and Commander color identity |
| `keywords`                                                | Array  | Keyword abilities on this printing |
| `legalities`                                              | Object | Format legality map — Standard, Modern, Commander, Pioneer, Pauper, Legacy, Vintage, and 17 more formats |
| `set` / `set_name` / `set_type`                           | String | Set code, name, and type |
| `collector_number`                                        | String | Collector number within the set |
| `rarity`                                                  | String | `common`, `uncommon`, `rare`, `mythic`, or special |
| `artist`                                                  | String | Card illustrator |
| `prices`                                                  | Object | USD, USD foil, USD etched, EUR, EUR foil, and MTGO (tix) prices |
| `tcgplayer_id` / `cardmarket_id` / `mtgo_id` / `arena_id` | Number | Marketplace and platform IDs for joining against other datasets |
| `image_uris`                                              | Object | Image URLs at several sizes |
| `card_faces`                                              | String | JSON-encoded face data for double-faced, split, or flip cards — empty for single-faced cards |
| `scryfall_uri`                                            | String | Permalink to this card on scryfall.com |
| `rulings_uri` / `prints_search_uri`                       | String | API URLs for this card's rulings and other printings |
| `edhrec_rank`                                             | Number | EDHRec popularity rank — lower is more popular |

***

### FAQ

#### How do I search for Magic: The Gathering cards by query?

Set `mode` to Search Query and give it a `query` using Scryfall's syntax — color, type, mana value, and format filters all combine, so `c:r t:creature cmc:3 f:standard` returns red three-mana creatures legal in Standard. Format legality and prices come back on every row.

#### How much does Scryfall MTG Cards Scraper cost to run?

It's floor-priced — a small per-record charge on top of a flat start fee, with no account or API key required to run it. A `maxItems` test run of five cards costs a few thousandths of a dollar.

#### Can I get every printing of a card, not just one?

Yes. Use Walk a Set with a three-letter set code to get every card in that set, or fetch the whole corpus with Bulk Dump and `unique_artwork` / `default_cards`, which return one row per distinct printing instead of one row per card name.

#### What happens if I look up a card name that doesn't exist?

By Name and By Scryfall ID modes skip a miss and keep going — a typo in a list of fifty names costs you one missing row, not a failed run.

#### Do I need an account or API key for Scryfall?

No. Scryfall is a public, unauthenticated API, and this scraper needs nothing from you beyond the input fields above.

***

### Need More Features?

Need a mode this doesn't cover, or want it paired with TCGPlayer or Cardmarket pricing? [File an issue](https://console.apify.com/actors/issues) or get in touch.

### Why Use Scryfall MTG Cards Scraper?

- **Floor-priced** — a fraction of a cent per card, cheaper than maintaining your own polite fetcher with rate-limit retries
- **Six modes in one schema** — search, name lookup, ID lookup, set walks, bulk dumps, and random pulls all return the same row shape, so switching modes doesn't mean rewriting your downstream code
- **Join-ready output** — TCGPlayer, Cardmarket, MTGO, and Arena IDs ship on every row, which is most of the work of combining this with a pricing or collection tool already done

# Actor input Schema

## `sp_intended_usage` (type: `string`):

What will this data feed? E.g. lead lists, KYB checks, price tracking.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

We'll personally help with your use case. No spam.

## `mode` (type: `string`):

Search by query, fetch by name, fetch by ID, walk a set, dump bulk data, or pull random cards.

## `query` (type: `string`):

Scryfall search syntax (e.g. "c:r t:creature cmc:3 f:standard"). Required when Mode is Search Query.

## `cardNames` (type: `array`):

Card names to look up. Required when Mode is By Name. Exact match unless "Use Fuzzy Name Lookup" is on.

## `cardIds` (type: `array`):

Scryfall card IDs to fetch. Required when Mode is By Scryfall ID.

## `setCode` (type: `string`):

Three-letter set code (e.g. "eld", "znr"). Required when Mode is Walk a Set.

## `bulkType` (type: `string`):

Which Scryfall bulk dump to ingest. Used when Mode is Bulk Dump.

## `fuzzyName` (type: `boolean`):

When Mode is By Name, use fuzzy match instead of exact match.

## `includePrices` (type: `boolean`):

Include USD / EUR / TIX prices in the output.

## `maxItems` (type: `integer`):

Maximum number of cards to return. 0 = unlimited (not allowed for Random Card mode, which caps at 50).

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "mode": "search",
  "query": "t:creature",
  "bulkType": "oracle_cards",
  "fuzzyName": false,
  "includePrices": true,
  "maxItems": 10
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "mode": "search",
    "query": "t:creature",
    "setCode": "",
    "bulkType": "oracle_cards",
    "fuzzyName": false,
    "includePrices": true,
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/scryfall-mtg-cards-api-wrapper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "mode": "search",
    "query": "t:creature",
    "setCode": "",
    "bulkType": "oracle_cards",
    "fuzzyName": False,
    "includePrices": True,
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/scryfall-mtg-cards-api-wrapper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "mode": "search",
  "query": "t:creature",
  "setCode": "",
  "bulkType": "oracle_cards",
  "fuzzyName": false,
  "includePrices": true,
  "maxItems": 10
}' |
apify call jungle_synthesizer/scryfall-mtg-cards-api-wrapper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jungle_synthesizer/scryfall-mtg-cards-api-wrapper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/cf8GqBTF31HANpE0k/builds/Gj3Lax1crRUNBExjP/openapi.json
