Developer API

Integrate Amalgadon board building and sharing into your own tools.

Overview

The Amalgadon API lets you create board builds programmatically and link users directly into the builder with a board pre-loaded. All endpoints are unauthenticated and free to use under the Terms of Service.

Base URL:

https://www.amalgadon.com

Card data is sourced from hearthstonejson.com. You can use POST /api/encode with card names rather than internal card IDs — the API resolves names for you so your integration does not depend on Hearthstone internals.

Rate Limits

Write endpoints are rate-limited per IP using a fixed window counter. Read-only endpoints have no limit.

EndpointLimitWindow
POST /api/encode30 requests60 seconds
POST /api/share30 requests60 seconds
GET /api/cardsUnlimited
GET /api/lookupUnlimited

When a limit is exceeded the response status is 429 with body {"error":"Rate limit exceeded"}.

GET /api/cards

Returns the full Battlegrounds card database used by the site.

GET/api/cards

No parameters. No authentication required.

Response

{
  "minions": [
    {
      "id": "BG21_002",
      "dbfId": 69448,
      "name": "Murloc Tidecaller",
      "text": "Whenever a friendly Murloc is summoned, gain +1 Attack.",
      "attack": 1,
      "health": 2,
      "techLevel": 1,
      "races": ["MURLOC"],
      "goldenCardId": "BG21_002_G"
    }
    // ...
  ],
  "heroes": [
    {
      "id": "BG_HERO_01",
      "dbfId": 53264,
      "name": "Patches the Pirate",
      "heroPowerText": "Give a friendly minion +2/+1.",
      "armor": 5
    }
    // ...
  ],
  "trinkets": [
    {
      "id": "BG30_MagicItem_901",
      "dbfId": 102847,
      "name": "Rock Buddy",
      "text": "After you play a minion, give it +2/+2.",
      "tier": "lesser"
    }
    // ...
  ],
  "spells": [
    {
      "id": "BG_Spell_001",
      "dbfId": 99001,
      "name": "Tavern Tipper",
      "cost": 1,
      "techLevel": 1
    }
    // ...
  ],
  "cacheTimestamp": 1713475200000
}
Note: Card IDs (e.g. BG21_002) are the internal Hearthstone identifiers from hearthstonejson.com. For most integrations you can pass card names to POST /api/encode instead and let the API resolve them — this is more readable and resilient to minor ID changes across patches.

GET /api/lookup

Resolves a card name or ID to its full card details and, where available, a link to the card's detail page on this site. Useful for building autocomplete UIs or validating card names before calling POST /api/encode.

GET/api/lookup

Query parameters

ParameterRequiredDescription
qYesCard name (fuzzy-matched) or exact card ID.
typeNoRestrict to a specific card type: minion, hero, trinket, or spell.

Examples

GET /api/lookup?q=Murloc+Tidecaller
GET /api/lookup?q=Brann&type=minion
GET /api/lookup?q=BG21_002

Success response — 200

{
  "results": [
    {
      "id":          "BG21_002",
      "name":        "Murloc Tidecaller",
      "type":        "minion",
      "fuzzy":       false,
      "text":        "Whenever a friendly Murloc is summoned, gain +1 Attack.",
      "attack":      1,
      "health":      2,
      "techLevel":   1,
      "races":       ["MURLOC"],
      "goldenCardId": "BG21_002_G",
      "detailUrl":   "https://www.amalgadon.com/minion/murloc-tidecaller"
    }
  ]
}
When type is omitted and a trinket name is shared across tiers, both the lesser and greater variants are returned as separate entries — each with a distinct id and tier field. Use the type=trinket filter and check the returned tier to distinguish them.

Error responses

StatusWhen
400Missing or empty q, or unrecognised type value.
404No card matched the query.

POST /api/encode

The primary integration endpoint. Accepts a human-readable board description, resolves card names to IDs, encodes the board, creates a shareable permalink, and returns all the URLs you need to link users into the builder.

POST/api/encode

Request body

FieldTypeRequiredDescription
herostringNoCard name or card ID of the hero.
slotsSlotInput[]Yes1–7 slot entries (null for empty slots).
lesserTrinketstring | nullNoCard name or card ID of the lesser trinket.
greaterTrinketstring | nullNoCard name or card ID of the greater trinket.
titlestringNoBuild title. Max 100 characters.
descriptionstringNoBuild notes. Max 2000 characters.

SlotInput object

FieldTypeRequiredDescription
namestringname or idMinion card name (recommended). Fuzzy-matched.
idstringname or idHearthstone card ID fallback.
goldenbooleanNoWhether the minion is golden.
tauntbooleanNoWhether the minion has Taunt.
rebornbooleanNoWhether the minion has Reborn.
divineShieldbooleanNoWhether the minion has Divine Shield.
At least one of name or id is required per slot. If name is provided it is always tried first. Name matching is case-insensitive and tolerates minor typos (fuzzy match). When a fuzzy match is used, the resolved block in the response will include "fuzzy": true — always log this during development to catch unexpected matches.
Trinket name disambiguation: Some trinkets share the same name across tiers. Name resolution for lesserTrinket is restricted to the lesser pool, and greaterTrinket to the greater pool — so the correct version is always matched even when names overlap. The tier field in the resolved block confirms which was matched.

Example request

POST /api/encode
Content-Type: application/json

{
  "hero": "Patches the Pirate",
  "slots": [
    { "name": "Murloc Tidecaller", "golden": false },
    { "name": "Sellemental", "golden": true },
    { "name": "Brann Bronzebeard", "taunt": true },
    null,
    null,
    null,
    null
  ],
  "lesserTrinket": "Rock Buddy",
  "title": "Murloc Tempo",
  "description": "Early curve into Murlocs with Brann for value."
}

Success response — 200

{
  "code": "pABCDEFGHIJKL...",
  "remixUrl": "https://www.amalgadon.com/?remix=pABCDEFGHIJKL...",
  "shareUrl":  "https://www.amalgadon.com/build/abc123",
  "embedUrl":  "https://www.amalgadon.com/embed/abc123",
  "resolved": {
    "hero":           { "name": "Patches the Pirate", "id": "BG_HERO_01",  "fuzzy": false },
    "slots": [
      { "name": "Murloc Tidecaller", "id": "BG21_002",  "fuzzy": false },
      { "name": "Sellemental",       "id": "BG20_204",  "fuzzy": false },
      { "name": "Brann Bronzebeard", "id": "BG_CFM_312","fuzzy": false },
      null,
      null,
      null,
      null
    ],
    "lesserTrinket":  { "name": "Rock Buddy", "id": "BG30_MagicItem_901", "fuzzy": false, "tier": "lesser" },
    "greaterTrinket": null
  }
}

Error responses

StatusWhen
400Malformed JSON, missing required fields, wrong types.
422One or more card names or IDs could not be resolved. See unresolved array.
429Rate limit exceeded.

A 422 response includes an unresolved array listing every field that failed resolution so you can address all problems in one cycle:

{
  "error": "Could not resolve some cards",
  "unresolved": [
    { "field": "slots[2]", "input": "Brann Bronzeberd" },
    { "field": "lesserTrinket", "input": "Rok Buddy" }
  ]
}

POST /api/share

Exchanges a full build code (the code field returned by POST /api/encode) for a 6-character short ID. Most integrations should use /api/encode directly — it calls this internally and returns the short ID for you.

POST/api/share

Request body

{ "code": "pABCDEFGHIJKL..." }

Success response — 200

{ "id": "abc123" }

The short ID can then be used to build deep-links (see below). If the same build code is submitted more than once, the same short ID is returned each time (deduplication is handled server-side).

Error reference

All error responses share the same shape:

{
  "error": "Human-readable message",
  // Optional — present on 422 responses only:
  "unresolved": [{ "field": "...", "input": "..." }]
}
StatusMeaning
200Success.
400Bad request — malformed JSON or invalid field values.
422Unprocessable — request was valid but one or more cards could not be resolved.
429Rate limit exceeded — retry after 60 seconds.
502Upstream error — card data could not be fetched from hearthstonejson.com.