Gather Developer API

Create collectible cards and drops with code.

You're a developer or an AI agent. You have images and ideas. The Gather API lets you turn them into tradeable digital collectible cards that fans can open in packs — no app needed, just GraphQL.

Two API calls to a live drop

🖼
Upload images
🚀
quickCreateDrop
Live!

One mutation creates all cards, variations, packs, and publishes the drop.

How It Works

Gather uses a simple content model. Everything chains together:

Card
A piece of artwork with a name, image, and tags. This is your base template.
↓ add rarity + finish
Variation
Same artwork, but with a rarity (Common → Legendary) and a finish (Holographic, Chrome, Gold Foil...). Each combination is a unique collectible.
↓ group into
Drop
A release containing your card variations, bundled into pack tiers. Fans mint packs and open them to reveal random cards.
Think of it like trading cards. You design the cards (artwork + stats), decide which are rare, put them in packs, and release them. The API handles everything else — minting, randomization, supply tracking, and on-chain provenance.

Connect Your API Key

Every request needs your API key in the Authorization header. Your key is tied to your brand — you can only create content for your own brand.

Every request looks like this
# Set these once — reuse everywhere
ENDPOINT="https://<your-appsync-id>.appsync-api.us-east-1.amazonaws.com/graphql"
API_KEY="gth_your_api_key_here"

curl -X POST "$ENDPOINT" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "...", "variables": { ... }}'
Format gth_ followed by 48 characters
Header Authorization: Bearer gth_...
Scope Locked to your brand — can't access other brands

Don't have a key yet? Contact the Gather team to get an API key for your brand.

Quick Start Create your first drop in 2 steps
1

Upload Your Images

Get your card artwork and drop cover into Gather's CDN.

Before you can create a drop, upload the images you'll use. This is a two-step process per image: ask for an upload URL, then PUT your file to it.

Ask for an upload URL

GraphQL
mutation {
  requestUploadUrl(input: {
    brandID: "BRAND_abc123"
    kind: "card-image"
    fileName: "rookie-debut.png"
  }) {
    uploadUrl
    publicUrl
    contentType
  }
}

You'll get back:

Upload the file

curl
# Use uploadUrl and contentType from the response above
curl -X PUT "${uploadUrl}" \
  -H "Content-Type: ${contentType}" \
  --data-binary @rookie-debut.png
Repeat for each image. Upload all your card artwork + the drop cover. Save each publicUrl — you'll use them in the next step.
Upload kinds reference
KindWhat it's for
card-imageCard artwork
coverDrop cover image
collectibleCollectible artwork
binder-coverBinder cover image
2

Create the Drop

One mutation. Cards, variations, packs, and publish — all at once.

quickCreateDrop is the fastest way to go from images to a live drop. You define your card designs, their rarity/finish variations, and pack configuration in a single call. The API creates everything for you.

GraphQL
mutation {
  quickCreateDrop(input: {
    brandID: "BRAND_abc123"
    brandName: "My Brand"
    title: "Season 1 — Rookie Class"
    description: "The debut collection featuring 2 rookies"
    coverImageUrl: "https://cdn.gather.fan/drops/s1-cover.png"
    maxPacksPerUser: 5
    autoPublish: true

    cards: [
      {
        name: "Rookie Debut"
        description: "The first card in the 2025 series"
        imageUrl: "https://cdn.gather.fan/cards/rookie-debut.png"
        tags: ["basketball", "rookie", "2025"]
        template: IMAGE_ONLY
        variations: [
          { rarity: COMMON,    finish: NON_HOLO,     supply: 200 }
          { rarity: UNCOMMON,  finish: REVERSE_HOLO, supply: 100 }
          { rarity: RARE,      finish: CHROME,        supply: 50 }
          { rarity: EPIC,      finish: GOLD_FOIL,     supply: 20 }
          { rarity: LEGENDARY, finish: HOLOGRAPHIC,   supply: 5 }
        ]
      }
      {
        name: "Rising Star"
        description: "Second pick of the draft"
        imageUrl: "https://cdn.gather.fan/cards/rising-star.png"
        tags: ["basketball", "star", "2025"]
        template: IMAGE_ONLY
        variations: [
          { rarity: COMMON,    finish: NON_HOLO,     supply: 200 }
          { rarity: UNCOMMON,  finish: REVERSE_HOLO, supply: 100 }
          { rarity: RARE,      finish: CHROME,        supply: 50 }
          { rarity: EPIC,      finish: GOLD_FOIL,     supply: 20 }
          { rarity: LEGENDARY, finish: HOLOGRAPHIC,   supply: 5 }
        ]
      }
    ]

    packTemplates: [
      {
        name: "Standard Pack"
        tier: "standard"
        supply: 400
        cardsPerPack: 3
        guaranteedMinRarity: "COMMON"
        price: 0
      }
      {
        name: "Premium Pack"
        tier: "premium"
        supply: 100
        cardsPerPack: 5
        guaranteedMinRarity: "RARE"
        price: 4.99
      }
    ]

    rarityDistribution: {
      common: 70
      rare: 25
      legendary: 5
    }
  }) {
    drop {
      dropID
      dropName
      totalPacks
      VISIBILITY_STATUS
      CREATION_STATUS
      collectibles { cardID name rarity finish supply }
      packTemplates { name tier supply cardsPerPack }
    }
    cardsCreated { cardID name rarity finish baseCardID }
  }
}
Response
{
  "data": {
    "quickCreateDrop": {
      "drop": {
        "dropID": "a1b2c3d4-...",
        "dropName": "Season 1 — Rookie Class",
        "totalPacks": 500,
        "VISIBILITY_STATUS": "VISIBLE",
        "CREATION_STATUS": "READY",
        "collectibles": [
          { "cardID": "...", "name": "Rookie Debut", "rarity": "COMMON", "finish": "NON_HOLO", "supply": 200 },
          { "cardID": "...", "name": "Rookie Debut", "rarity": "LEGENDARY", "finish": "HOLOGRAPHIC", "supply": 5 }
        ],
        "packTemplates": [
          { "name": "Standard Pack", "tier": "standard", "supply": 400, "cardsPerPack": 3 },
          { "name": "Premium Pack", "tier": "premium", "supply": 100, "cardsPerPack": 5 }
        ]
      },
      "cardsCreated": [
        { "cardID": "...", "name": "Rookie Debut", "rarity": null, "finish": null, "baseCardID": null },
        { "cardID": "...", "name": "Rookie Debut", "rarity": "COMMON", "finish": "NON_HOLO", "baseCardID": "..." }
      ]
    }
  }
}
Your drop is live!

With autoPublish: true, the drop is immediately visible to fans. Cards, variations, pack tiers — everything was created in that single call.

What happens behind the scenes

cards Each card entry creates a base template plus one variation per rarity/finish combo. All cards are stored in DynamoDB.
variations Each { rarity, finish, supply } triple becomes a collectible card in the drop. Supply controls how many of that variation exist.
packTemplates Defines different pack tiers. Each tier has its own supply, cards per pack, price, and guaranteed rarity.
autoPublish Set to true to go live immediately. Set to false (or omit) to create the drop hidden, then publish later with publishDrop.
What the rarity distribution means: common: 70 = 70% chance of pulling a Common, rare: 25 = 25% Rare, legendary: 5 = 5% Legendary. These are the odds for each card slot when a fan opens a pack.

What you just did

StepAPI CallCount
Upload card imagesrequestUploadUrl + HTTP PUT1 per image
Upload drop coverrequestUploadUrl + HTTP PUT1
Create everythingquickCreateDrop1

For a drop with 4 card designs and 5 variations each: 5 API calls total (4 image uploads + 1 cover upload + 1 quickCreateDrop). That's it.

End-to-End Example

Complete Script: Images to Live Drop

This is a full, runnable bash script that takes a folder of images and creates a published drop. Copy it, set your variables, and run it. This is the exact workflow an AI agent should follow.

For AI agents: This is the reference implementation. Follow this pattern: upload images, collect URLs, call quickCreateDrop, done. The entire process is 1 GraphQL call per image + 1 final call.
bash — Complete drop creation script
#!/usr/bin/env bash
set -euo pipefail

# ── Configuration ──────────────────────────────────────────
# Replace these with your actual values
ENDPOINT="https://<your-appsync-id>.appsync-api.us-east-1.amazonaws.com/graphql"
API_KEY="gth_your_api_key_here"
BRAND_ID="BRAND_your_brand_id"
BRAND_NAME="Your Brand"

# ── Helper: send a GraphQL request ────────────────────────
gql() {
  local query="$1"
  local variables="${2:-{}}"
  local payload
  payload=$(jq -n --arg q "$query" --argjson v "$variables" \
    '{query: $q, variables: $v}')
  curl -s -X POST "$ENDPOINT" \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: application/json" \
    -d "$payload"
}

# ── Helper: upload one image ──────────────────────────────
upload_image() {
  local file_path="$1"
  local kind="$2"  # "card-image" or "cover"
  local file_name
  file_name=$(basename "$file_path")

  # Step A: Get a presigned upload URL
  local result
  result=$(gql 'mutation($input: RequestUploadUrlInput!) {
    requestUploadUrl(input: $input) {
      uploadUrl
      publicUrl
      contentType
    }
  }' "$(jq -cn \
    --arg bid "$BRAND_ID" \
    --arg kind "$kind" \
    --arg fn "$file_name" \
    '{input: {brandID: $bid, kind: $kind, fileName: $fn}}')")

  local upload_url public_url content_type
  upload_url=$(echo "$result" | jq -r '.data.requestUploadUrl.uploadUrl')
  public_url=$(echo "$result" | jq -r '.data.requestUploadUrl.publicUrl')
  content_type=$(echo "$result" | jq -r '.data.requestUploadUrl.contentType')

  # Step B: PUT the file to S3
  curl -s -X PUT "$upload_url" \
    -H "Content-Type: $content_type" \
    --data-binary "@$file_path" > /dev/null

  echo "$public_url"
}

# ── Step 1: Upload card images ────────────────────────────
echo "Uploading card images..."
CARD1_URL=$(upload_image "images/warrior.png" "card-image")
CARD2_URL=$(upload_image "images/mage.png" "card-image")
CARD3_URL=$(upload_image "images/rogue.png" "card-image")

echo "Uploading cover..."
COVER_URL=$(upload_image "images/cover.png" "cover")

echo "All images uploaded."

# ── Step 2: Create the drop ───────────────────────────────
echo "Creating drop..."
VARIABLES=$(jq -cn \
  --arg brandID  "$BRAND_ID" \
  --arg brandName "$BRAND_NAME" \
  --arg card1 "$CARD1_URL" \
  --arg card2 "$CARD2_URL" \
  --arg card3 "$CARD3_URL" \
  --arg cover "$COVER_URL" \
  '{
    input: {
      brandID: $brandID,
      brandName: $brandName,
      title: "Fantasy Heroes Collection",
      description: "Three legendary heroes. Collect them all.",
      coverImageUrl: $cover,
      maxPacksPerUser: 5,
      autoPublish: true,

      cards: [
        {
          name: "Shadow Warrior",
          description: "A blade in the dark",
          imageUrl: $card1,
          tags: ["fantasy", "warrior"],
          template: "IMAGE_ONLY",
          variations: [
            { rarity: "COMMON",    finish: "NON_HOLO",     supply: 100 },
            { rarity: "RARE",      finish: "HOLOGRAPHIC",   supply: 20 },
            { rarity: "LEGENDARY", finish: "CHROME",        supply: 3 }
          ]
        },
        {
          name: "Arcane Mage",
          description: "Master of the elements",
          imageUrl: $card2,
          tags: ["fantasy", "mage"],
          template: "IMAGE_ONLY",
          variations: [
            { rarity: "COMMON",    finish: "NON_HOLO",     supply: 100 },
            { rarity: "RARE",      finish: "GALAXY",        supply: 15 },
            { rarity: "LEGENDARY", finish: "GOLD_FOIL",     supply: 2 }
          ]
        },
        {
          name: "Night Rogue",
          description: "Strikes without warning",
          imageUrl: $card3,
          tags: ["fantasy", "rogue"],
          template: "IMAGE_ONLY",
          variations: [
            { rarity: "COMMON",    finish: "NON_HOLO",     supply: 80 },
            { rarity: "RARE",      finish: "HOLOGRAPHIC",   supply: 25 },
            { rarity: "LEGENDARY", finish: "PRISMATIC",     supply: 5 }
          ]
        }
      ],

      packTemplates: [
        {
          name: "Standard Pack",
          tier: "standard",
          supply: 100,
          cardsPerPack: 5,
          guaranteedMinRarity: "COMMON",
          price: 0
        }
      ],

      rarityDistribution: {
        common: 60,
        rare: 25,
        legendary: 15
      }
    }
  }')

RESULT=$(gql 'mutation($input: QuickCreateDropInput!) {
  quickCreateDrop(input: $input) {
    drop {
      dropID
      dropName
      totalPacks
      totalCards
      VISIBILITY_STATUS
      CREATION_STATUS
      collectibles { name rarity finish supply }
      packTemplates { name tier supply cardsPerPack }
    }
    cardsCreated { cardID name rarity finish }
  }
}' "$VARIABLES")

# ── Step 3: Verify ────────────────────────────────────────
DROP_ID=$(echo "$RESULT" | jq -r '.data.quickCreateDrop.drop.dropID')
STATUS=$(echo "$RESULT" | jq -r '.data.quickCreateDrop.drop.VISIBILITY_STATUS')

echo ""
echo "Drop created!"
echo "  ID:     $DROP_ID"
echo "  Status: $STATUS"
echo ""
echo "Collectibles:"
echo "$RESULT" | jq -r '.data.quickCreateDrop.drop.collectibles[]
  | "  - \(.name) [\(.rarity)] \(.finish) (supply: \(.supply))"'
echo ""
echo "Done — drop is live in the Gather app!"

What this script does

upload_image Calls requestUploadUrl to get a presigned S3 URL, then PUTs the file to it. Returns the permanent CDN URL.
quickCreateDrop One mutation that creates 3 base cards + 9 variations + the drop + pack templates, and publishes it. All in one call.
autoPublish: true Makes the drop visible immediately. Set to false to create it hidden, then call publishDrop when ready.
Total API calls: 4 image uploads (3 cards + 1 cover) + 1 quickCreateDrop = 5 GraphQL calls. That's it for a complete, published drop with 9 collectible variations.

Key rules for AI agents

RuleDetails
Upload images first You must call requestUploadUrl + PUT for each image before referencing it in quickCreateDrop. The imageUrl and coverImageUrl fields expect the publicUrl returned by the upload step.
Use the correct brandID Your API key is scoped to one brand. Pass that exact brandID (e.g. BRAND_abc123) in every mutation. A mismatch returns UnauthorizedError.
rarityDistribution only has 3 fields The input accepts common, rare, and legendary only. These are weight percentages (e.g. 60 / 25 / 15). Cards with UNCOMMON or EPIC rarity still work — the distribution maps them to the nearest tier.
Max 50 variations per call quickCreateDrop supports up to 50 total card variations across all cards. For larger drops, use multiple createCardWithVariations calls + createDrop.
Verify with getDrop After creating, query getDrop(dropID) to confirm the drop is VISIBLE and all collectibles + pack templates are correct.

Discovering your brand ID

If you don't know your brandID, query any of your existing data:

GraphQL
# Works with any API key — returns your brand from existing drops
query { listVisibleDrops(limit: 1) { items { brandID brandName } } }

# Or from your cards
query { listCards(limit: 1) { items { brandID brandName } } }

Step-by-Step (Advanced)

If you need more control over each step, you can use the individual mutations instead of quickCreateDrop.

Option A: createCardWithVariations + createDrop

Create cards and variations in one call per card design, then assemble the drop manually.

GraphQL — Create card + variations
mutation {
  createCardWithVariations(input: {
    brandID: "BRAND_abc123"
    brandName: "My Brand"
    name: "Rookie Debut"
    description: "The first card in the 2025 series"
    imageUrl: "https://cdn.gather.fan/cards/rookie-debut.png"
    tags: ["basketball", "rookie", "2025"]
    template: IMAGE_ONLY
    variations: [
      { rarity: COMMON,    finish: NON_HOLO,     supply: 200 }
      { rarity: RARE,      finish: CHROME,        supply: 50 }
      { rarity: LEGENDARY, finish: HOLOGRAPHIC,   supply: 5 }
    ]
  }) {
    baseCard { cardID name }
    variations { cardID rarity finish }
  }
}

Then use the returned card IDs to assemble a drop with createDrop + publishDrop.

Option B: Fully manual (createCard one at a time)

Create each card individually with createCard, set baseCardID for variations, then build the drop. See the Reading Data section for how to verify each step.

GraphQL — Create base card
mutation {
  createCard(input: {
    brandID: "BRAND_abc123"
    brandName: "My Brand"
    name: "Rookie Debut"
    imageUrl: "https://cdn.gather.fan/cards/rookie-debut.png"
    tags: ["basketball", "rookie"]
    template: IMAGE_ONLY
  }) {
    cardID
    name
  }
}
GraphQL — Create variation
mutation {
  createCard(input: {
    brandID: "BRAND_abc123"
    brandName: "My Brand"
    name: "Rookie Debut"
    imageUrl: "https://cdn.gather.fan/cards/rookie-debut.png"
    tags: ["basketball", "rookie"]
    template: IMAGE_ONLY
    baseCardID: "CARD_f7a2b9c1"
    rarity: LEGENDARY
    finish: HOLOGRAPHIC
  }) {
    cardID
    rarity
    finish
  }
}
Comparison: quickCreateDrop = 5 API calls for a typical drop. createCardWithVariations + createDrop = ~9 calls. Fully manual = ~28 calls. All three produce the same result.
3

Retrieve Your Data

Look up your cards, variations, and drops at any time.

Lost a drop ID or card ID? No problem. You can always list everything your brand has created. All queries work with your API key — just use your brandID to filter.

List all your cards (base templates)

GraphQL
query {
  getBrandCards(brandID: "BRAND_abc123", cardType: TEMPLATE, limit: 50) {
    items {
      cardID
      name
      imageUrl
      template
      status
      createdAt
    }
    nextToken
  }
}

List all variations for a brand

GraphQL
query {
  getBrandCards(brandID: "BRAND_abc123", cardType: VARIATION, limit: 50) {
    items {
      cardID
      baseCardID
      name
      rarity
      finish
      template
      status
    }
    nextToken
  }
}

List all your drops

GraphQL
query {
  getBrandDrops(brandID: "BRAND_abc123") {
    dropID
    dropName
    totalPacks
    mintedPacks
    VISIBILITY_STATUS
    PAUSED
    createdAt
    packTemplates {
      name
      tier
      supply
      mintedCount
    }
  }
}

Get full details for a specific drop

GraphQL
query {
  getDrop(dropID: "a1b2c3d4-...") {
    dropID
    dropName
    totalPacks
    mintedPacks
    VISIBILITY_STATUS
    CREATION_STATUS
    collectibles {
      cardID
      baseCardID
      name
      rarity
      finish
      supply
      mintedCount
    }
    packTemplates {
      packID
      name
      tier
      supply
      mintedCount
      cardsPerPack
      price
    }
  }
}

Look up a single card

GraphQL
query {
  getCard(cardID: "your-card-id-here") {
    cardID
    baseCardID
    name
    rarity
    finish
    template
    imageUrl
    tags
    status
    createdAt
  }
}
All available queries
QueryWhat it returns
getCard(cardID)Single card by ID
getBrandCards(brandID)All cards for a brand (filter by cardType: TEMPLATE or VARIATION)
listCardsAll cards on the platform
getDrop(dropID)Single drop with full details + collectibles + pack templates
getBrandDrops(brandID)All drops for a brand
listVisibleDropsPublished, active drops only
getDropCollectibles(dropID)All minted collectibles from a drop
getDropPacks(dropID)All packs minted from a drop
getNumberCollectors(brandID)Unique collector count for a brand
Reference

Query Gather

Every query below works with your API key. Use them to explore your content, check drop stats, or recover lost IDs.

Cards

QueryWhat it returnsKey arguments
getCard(cardID) A single card — base template or variation cardID: ID!
getBrandCards(brandID) All cards for your brand, paginated cardType: TEMPLATE | VARIATION, status, limit, nextToken
listCards All cards on the platform, paginated cardType, status, limit, nextToken
Example — Get all base templates for your brand
query {
  getBrandCards(brandID: "BRAND_abc123", cardType: TEMPLATE, limit: 50) {
    items {
      cardID
      name
      imageUrl
      template
      status
      createdAt
    }
    nextToken
  }
}
Example — Get all variations for your brand
query {
  getBrandCards(brandID: "BRAND_abc123", cardType: VARIATION, limit: 50) {
    items {
      cardID
      baseCardID
      name
      rarity
      finish
      template
      imageUrl
    }
    nextToken
  }
}

Drops

QueryWhat it returnsKey arguments
getDrop(dropID) Full drop details including collectibles and pack templates dropID: ID!
getBrandDrops(brandID) All drops for your brand brandID: ID!
listDrops All drops sorted by start time, paginated limit, nextToken
listVisibleDrops Only published, non-paused drops brandID (optional filter), limit, nextToken
Example — List your drops with mint progress
query {
  getBrandDrops(brandID: "BRAND_abc123") {
    dropID
    dropName
    totalPacks
    mintedPacks
    mintedCards
    VISIBILITY_STATUS
    CREATION_STATUS
    PAUSED
    startsAt
    createdAt
  }
}
Example — Full drop detail with collectibles
query {
  getDrop(dropID: "your-drop-id") {
    dropID
    dropName
    description
    coverImageUrl
    totalPacks
    mintedPacks
    totalCards
    mintedCards
    maxPacksPerUser
    VISIBILITY_STATUS
    CREATION_STATUS
    PAUSED
    startsAt
    endsAt
    collectibles {
      cardID
      baseCardID
      name
      rarity
      finish
      supply
      mintedCount
    }
    packTemplates {
      packID
      name
      tier
      supply
      mintedCount
      cardsPerPack
      guaranteedMinRarity
      price
    }
    rarityDistribution { common uncommon rare epic legendary }
    rarityMinted { common uncommon rare epic legendary }
  }
}

Collectibles & Packs

QueryWhat it returnsKey arguments
getDropCollectibles(dropID) All minted collectibles from a drop, paginated dropID: ID!, limit, nextToken
getUserCollectibles(userID) All collectibles owned by a specific user userID: ID!
getDropPacks(dropID) All packs minted from a drop, paginated dropID: ID!, limit, nextToken
getUserPacks(userID) All packs owned by a user status: "SEALED" | "OPENED", limit, nextToken
getPack(packID) A single pack by ID packID: ID!
getUserPackCount(userID, dropID) How many packs a user claimed from a drop userID: ID!, dropID: ID!
Example — See who minted from your drop
query {
  getDropCollectibles(dropID: "your-drop-id", limit: 20) {
    items {
      collectibleID
      userID
      cardID
      name
      rarity
      finish
      onChainStatus
      createdAt
    }
    nextToken
  }
}

Brand Stats

QueryWhat it returnsKey arguments
getNumberCollectors(brandID) Total unique collectors for your brand brandID: ID!
getCollectibleStats Platform-wide stats: total, minted, pending, not minted None
getRecentMintActivity Live feed of recent pack mints across all drops limit, nextToken
Example — Check your collector count
query {
  getNumberCollectors(brandID: "BRAND_abc123") {
    brandID
    collectorCount
  }
}

Binders

QueryWhat it returnsKey arguments
getBinder(binderID) A single binder with slot requirements binderID: ID!
getBrandBinders(brandID) All binders for your brand, paginated brandID: ID!, limit, nextToken
listBinders All binders on the platform, paginated limit, nextToken
getUserBinderProgress(userID, binderID) A user's progress on a specific binder userID: ID!, binderID: ID!
Pagination. Queries that return lists support limit and nextToken. Pass the nextToken from one response into the next request to get the next page.

Managing Drops After Launch

You have full control over your drop after publishing.

Pause minting

Temporarily stop pack sales

pauseDrop(dropID)

Resume minting

Restart pack sales

unpauseDrop(dropID)

Hide the drop

Remove from public view

unpublishDrop(dropID)

Update details

Change title, limits, timing

updateDrop(dropID, input)

Delete the drop

Remove permanently

deleteDrop(dropID)

Update a card

Change name, desc, status

updateCard(input)

Rarities & Finishes

Rarities

Set on each card variation. Determines pull rate in packs.

COMMON Most frequent pull
UNCOMMON Slightly less common
RARE Hard to find
EPIC Very rare
LEGENDARY The chase card — rarest tier

Finishes

Visual effects applied to the card. Pair with rarity for unique combinations.

NON_HOLO
REVERSE_HOLO
HOLOGRAPHIC
TEXTURED
CHROME
GALAXY
PRISMATIC
GOLD_FOIL
NEON_GLOW
CRACKED_ICE
LAVA
SHADOW
GLITCH
AURORA

Card Templates

The template field controls the visual frame around your card artwork. Each template defines the card's border style, header, name plate, footer, and accent colors. Below are blank previews of all 12 templates.

BRAND RARE DESCRIPTION CARD NAME HOLOGRAPHIC
SPORTS
Bold athletic card
B CARD NAME NON HOLO
IMAGE_ONLY
Full-bleed image, no frame — default
BRAND RARE CARD NAME HOLOGRAPHIC
GAMING
Neon-green HUD, dark charcoal
BRAND ★★★ CARD NAME HOLOGRAPHIC
CLASSIC_TCG
Ornate gold borders, parchment
BRAND RARE CARD NAME HOLOGRAPHIC
ANIME
Vibrant pink + blue, speed lines
BRAND RARE CARD NAME HOLOGRAPHIC
CYBERPUNK
Cyan + magenta neon, circuit frame
BRAND CARD NAME NON HOLO
MINIMALIST
Clean white space, gallery art vibe
BRAND RARE CARD NAME HOLOGRAPHIC
VINTAGE
Sepia tones, film grain, retro
BRAND RARE CARD NAME HOLOGRAPHIC
LUXURY
Matte black, gold foil accents
BRAND RARE CARD NAME NON HOLO
BOTANICAL
Earth tones, vine accents, ivory
BRAND RARE CARD NAME DESCRIPTION HOLOGRAPHIC
STREET
Urban graffiti, spray-paint red
BRAND RARE CARD NAME HOLOGRAPHIC
COSMIC
Deep space, constellations, nebula
Default template If you omit the template field, cards use IMAGE_ONLY by default — a full-bleed image with no frame, header, or footer, just a floating brand badge and name overlay. Use a named template like SPORTS or GAMING for a framed card layout.

Errors

When something goes wrong, the API returns an error in the standard GraphQL format:

Error response
{
  "data": null,
  "errors": [{
    "errorType": "UnauthorizedError",
    "message": "Not authorized for this brand"
  }]
}
ErrorWhy it happenedFix
UnauthorizedError Wrong brandID or invalid key Check your API key and use the correct brandID
RateLimitExceeded Too many requests per minute Wait a few seconds, then retry
UploadError Bad upload kind or file name Use one of: card-image, cover, collectible, binder-cover
ConditionalCheckFailed Resource conflict (e.g. duplicate) Check if the resource already exists

Rate Limits

Standard
60
requests / minute
Premium
300
requests / minute

Creating a typical drop with quickCreateDrop takes about 5 calls — well within the standard tier limit. Even the manual approach (~28 calls) fits comfortably.