Skip to content
IN THIS GUIDE

GraveMint v1 API ​

Base URL — https://api.solanadeads.com/gravemint/v1

Recorded responses below show the API output at capture time. Live consoles let you inspect current responses for the sample collection.

Authentication ​

Choose a key for the environment making the request.

headerbounded byuse it
PublishableX-API-Key: gm_pub_…the origin allow-list on the keyin your web page
SecretX-API-Key: gm_live_…secrecyfrom your server

Use a publishable key in browser applications and a secret key on your server. Register each browser origin, including staging and previews, and keep server keys out of browser bundles. See keys and origins for sandbox keys and collection scope.

Try it live ​

Examples in

Use Send to inspect the request and response, including status and timing. The consoles use a sandbox key scoped to DEAD DAWGS — ONCHAIN TEST on solana-devnet. This key is restricted to registered documentation origins, the sample collection and test networks.

Preparation makes a live devnet request and may reserve supply when a funded wallet is supplied. Execution is an example builder: it requires a wallet-signed transaction and cannot be sent from this page.

Discovery ​

GET/

No parameters. Confirms the surface and its stability contract.

Sent

GET https://api.solanadeads.com/gravemint/v1/
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const result = await gm.v1.version();
console.log(result);

Read a drop ​

Address a collection by its short ID, UUID or on-chain address. Use short IDs in public links and preserve address case.

GET/collections/{identifier}

Everything needed to build a mint page, in one call.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const collection = await gm.v1.collection("7zn5qa");
console.log(collection);

Where are the sales phases? ​

The collection response includes phases: { active, upcoming, all }. Each array contains phase schedules, wallet limits and resolved priceDisplay values. The response also includes serverTime for countdowns.

Use the returned phase status. GraveMint manages phase transitions on the server; refresh the collection response when a countdown expires to obtain the current state.

Check eligibility ​

Server-side verdict for one wallet against one phase. Gating criteria stay on our side — you receive the decision, never the allowlist.

GET/collections/{collectionId}/eligibility/{phaseId}/{walletAddress}

Checks wallet requirements. phase.hasStarted and phase.hasEnded report the time window separately.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/eligibility/8426923e-0d64-480d-925f-90324c2dedf5/11111111111111111111111111111111
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const eligibility = await gm.v1.eligibility("7zn5qa", "8426923e-0d64-480d-925f-90324c2dedf5", "11111111111111111111111111111111");
console.log(eligibility);

The rest of the drop ​

Everything else a mint page is built from, scoped to the key the same way.

The sample key is scoped to one collection. Requests for another collection return 403 COLLECTION_NOT_IN_SCOPE.

GET/collections/{identifier}/gallery

Available artwork, with limit and offset pagination.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/gallery?limit=3
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const gallery = await gm.v1.gallery("7zn5qa", {
  limit: 3,
});
console.log(gallery);
GET/collections/{identifier}/recently-minted

The live 'just minted' feed.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/recently-minted?limit=3
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const recentlyMinted = await gm.v1.recentlyMinted("7zn5qa", {
  limit: 3,
});
console.log(recentlyMinted);
GET/collections/{collectionId}/wallet-mints/{walletAddress}

Minted and remaining counts per phase, including bonus mints. Use this response for wallet counts; eligibility uses separate allocation rules.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/wallet-mints/11111111111111111111111111111111
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const walletMints = await gm.v1.walletMints("7zn5qa", "11111111111111111111111111111111");
console.log(walletMints);
GET/collections/{identifier}/bounty

Bounty configuration and rewards. Collections without a bounty return an empty summary.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/bounty
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const bounty = await gm.v1.bounty("7zn5qa");
console.log(bounty);
GET/collections/{identifier}/bounty-prizes

The public prize table. Returns enabled: false when there is no bounty.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/bounty-prizes
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const bountyPrizes = await gm.v1.bountyPrizes("7zn5qa");
console.log(bountyPrizes);

Claim codes ​

Read the collection's code configuration and the benefits a wallet has already redeemed. Validation checks a code without redeeming it or consuming a use.

GET/collections/{collectionId}/claim-codes

Does this drop use codes, and of what kind?

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/claim-codes
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const claimCodes = await gm.v1.claimCodes("7zn5qa");
console.log(claimCodes);
GET/collections/{collectionId}/claim-codes/benefits/{walletAddress}

What a wallet is already entitled to from codes it has redeemed.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/claim-codes/benefits/11111111111111111111111111111111
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const claimCodeBenefits = await gm.v1.claimCodeBenefits("7zn5qa", "11111111111111111111111111111111");
console.log(claimCodeBenefits);
POST/collections/{collectionId}/claim-codes/validate

READ-ONLY — checking a code does not redeem it or consume a use.

Sent

POST https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/claim-codes/validate
X-API-Key: gm_test_47716d…
Content-Type: application/json

{
  "code": "TRY-A-CODE"
}

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const validateClaimCode = await gm.v1.validateClaimCode("7zn5qa", "TRY-A-CODE");
console.log(validateClaimCode);

Pricing ​

Use priceDisplay on the phase for the initial display. Pegged prices can be marked approximate. The helpers below refresh pegged or Dutch prices without reloading the collection.

GET/token-prices

Platform token prices — what an SPL-priced drop is worth in USD. Global: it names no collection, so it carries no drop data and needs no collection scope.

Sent

GET https://api.solanadeads.com/gravemint/v1/token-prices
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const getTokenPrices = await gm.platform.getTokenPrices();
console.log(getTokenPrices);
GET/phases/{phaseId}/pegged-price

The resolved amount for a USD- or native-pegged phase. Scoped through the phase's own collection — a phase id is not a way around collection scope.

Sent

GET https://api.solanadeads.com/gravemint/v1/phases/8426923e-0d64-480d-925f-90324c2dedf5/pegged-price
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const peggedPrice = await gm.v1.peggedPrice("8426923e-0d64-480d-925f-90324c2dedf5");
console.log(peggedPrice);
GET/phases/{phaseId}/dutch-price

The live price of a dynamic Dutch phase, which moves with time.

Sent

GET https://api.solanadeads.com/gravemint/v1/phases/8426923e-0d64-480d-925f-90324c2dedf5/dutch-price
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const dutchPrice = await gm.v1.dutchPrice("8426923e-0d64-480d-925f-90324c2dedf5");
console.log(dutchPrice);

Supply, traits and social proof ​

GET/collections/{collectionId}/availability

Approximate supply counts, including burned items. available may be null for open-ended supply; pending reservations can still appear available.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/availability
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const availability = await gm.v1.availability("7zn5qa");
console.log(availability);
GET/collections/{identifier}/traits

Trait names and values, for filtering a gallery.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/traits
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const traits = await gm.v1.traits("7zn5qa");
console.log(traits);
GET/collections/{identifier}/all-minted

One page of minted items. Continue with limit and offset for a full history.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/all-minted
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const allMinted = await gm.v1.allMinted("7zn5qa");
console.log(allMinted);
GET/collections/{identifier}/top-holders

Largest holders.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/top-holders
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const topHolders = await gm.v1.topHolders("7zn5qa");
console.log(topHolders);
GET/collections/{identifier}/top-minters

Who minted the most.

Sent

GET https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/top-minters
X-API-Key: gm_test_47716d…

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const topMinters = await gm.v1.topMinters("7zn5qa");
console.log(topMinters);

What your key can reach ​

Every route that names a collection is scoped to the collections your key was issued for. Measured against production with a key scoped to one drop, asking for another:

RequestResult
GET /collections/{other}403 COLLECTION_NOT_IN_SCOPE
GET /collections/{other}/gallery403
GET /collections/{other}/recently-minted403
GET /collections/{other}/bounty · /bounty-prizes403
GET /collections/{other}/wallet-mints/{wallet}403
GET /collections/{other}/eligibility/{phase}/{wallet}403
POST /prepare-mint with another drop's id403
GET / (version — names no collection)200

The refusal is deliberately identical whether or not the drop exists, so an unauthorised caller learns only that this key cannot read it — never whether the collection is real.

Two further bounds apply on top of scope: a key with an origin list is refused from any other origin (403 ORIGIN_NOT_ALLOWED, including a request with no Origin at all, which is why a browser key cannot be used server-side), and a sandbox key is refused on any production chain (403 SANDBOX_KEY_ON_MAINNET).

Prepare a mint ​

Preparation checks eligibility, pricing and supply, then creates transactions for signing. The default sample wallet is expected to return INSUFFICIENT_BALANCE before a supply reservation. A funded devnet wallet can receive transactions and sessions, reserving devnet supply for the session lifetime.

POST/prepare-mint

Returns transactions for your wallet to sign and GraveMint to submit.

Sent

POST https://api.solanadeads.com/gravemint/v1/prepare-mint
X-API-Key: gm_test_47716d…
Content-Type: application/json

{
  "collectionId": "2e239364-fc9b-4191-ba62-b57dbac76394",
  "phaseId": "8426923e-0d64-480d-925f-90324c2dedf5",
  "walletAddress": "11111111111111111111111111111111",
  "quantity": "1"
}

Received

Nothing yet — press Send.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const result = await gm.mint.prepare({
  collectionId: "2e239364-fc9b-4191-ba62-b57dbac76394",
  phaseId: "8426923e-0d64-480d-925f-90324c2dedf5",
  walletAddress: "11111111111111111111111111111111",
  quantity: 1,
});
console.log(result);

Execute a mint ​

POST/execute-mintnot sent

Send the signed transaction as base64. A transactionHash returns CLIENT_BROADCAST_NOT_ALLOWED.

Example only. Supply a wallet-signed transaction in your application to execute a mint.

Sent

POST https://api.solanadeads.com/gravemint/v1/execute-mint
X-API-Key: gm_test_47716d…
Content-Type: application/json

{
  "sessionId": "<from prepare-mint>",
  "signedTransaction": "<base64 signed tx>"
}

Received

This request is shown, not sent.
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_test_your_key" });

const result = await gm.mint.execute({
  sessionId: "<from prepare-mint>",
  signedTransaction: "<base64 signed tx>",
});
console.log(result);

Recorded responses ​

These examples were captured from the API. Sample collection data can change; use the consoles above for current values.

Discovery ​

Confirms the surface and its stability contract.

js
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_pub_your_key" });

const result = await gm.v1.version();
console.log(result);
ts
import { GraveMintClient, GraveMintError } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_pub_your_key" });

try {
  const result = await gm.v1.version();
  console.log(result);
} catch (err) {
  // `code` is stable — branch on it. `message` is a sentence you can show a user.
  if (err instanceof GraveMintError) console.error(err.code, err.message);
  else throw err;
}
bash
curl -s \
  -H 'X-API-Key: gm_pub_your_key' \
  'https://api.solanadeads.com/gravemint/v1/'
json
{
  "success": true,
  "version": "v1",
  "stability": "additive-only",
  "docs": "https://www.npmjs.com/package/@solanadeads/gravemint"
}

Reading a drop ​

One call returns everything needed to build a mint page: the collection, every phase with its resolved price, live supply, and our clock for countdowns.

Use the collection's short ID, UUID or on-chain address. Recorded examples can reflect an earlier API deployment; the published SDK reference describes the current identifier contract.

GET /v1/collections/:identifier ​

js
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_pub_your_key" });

const collection = await gm.v1.collection("7zn5qa");
console.log(collection);
ts
import { GraveMintClient, GraveMintError, type V1Collection } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_pub_your_key" });

try {
  const collection: V1Collection = await gm.v1.collection("7zn5qa");
  console.log(collection);
} catch (err) {
  // `code` is stable — branch on it. `message` is a sentence you can show a user.
  if (err instanceof GraveMintError) console.error(err.code, err.message);
  else throw err;
}
bash
curl -s \
  -H 'X-API-Key: gm_pub_your_key' \
  'https://api.solanadeads.com/gravemint/v1/collections/7zn5qa'
json
{
  "success": true,
  "collection": {
    "id": "2e239364-fc9b-4191-ba62-b57dbac76394",
    "shortId": "7zn5qa",
    "name": "DEAD DAWGS - ONCHAIN TEST",
    "symbol": "ONCHAIN1",
    "description": "Testing",
    "image": "https://gravemint-storage.s3.us-east-1.amazonaws.com/launchpad-collection-images/1774886146380/collection.png",
    "bannerImage": "https://gravemint-storage.s3.us-east-1.amazonaws.com/launchpad-collection-images/1774886157110/banner.png",
    "chain": "solana-devnet",
    "collectionAddress": "7mS96x56GoeE23R8DRXYusjecFY9udEw2NTnedqJ1Ed5",
    "contractAddress": null,
    "externalUrl": null,
    "twitter": null,
    "discord": null,
    "isVerified": false
  },
  "stats": {
    "totalSupply": 888,
    "mintedCount": 21,
    "availableCount": 867,
    "percentMinted": 2.364864864864865
  },
  "phases": {
    "all": [
      {
        "id": "8426923e-0d64-480d-925f-90324c2dedf5",
        "name": "Public",
        "status": "active",
        "startDate": "2026-03-30T16:02:00.000Z",
        "endDate": null,
        "priceDisplay": {
          "kind": "amount",
          "amount": 1,
          "currency": "USD",
          "isFree": false
        },
        "bogo": null,
        "isGated": false,
        "maxPerWallet": 100,
        "maxPerTransaction": 10,
        "phaseSupply": null,
        "msUntilStart": null,
        "msUntilEnd": null
      }
    ],
    "active": [
      {
        "id": "8426923e-0d64-480d-925f-90324c2dedf5",
        "name": "Public",
        "status": "active",
        "startDate": "2026-03-30T16:02:00.000Z",
        "endDate": null,
        "priceDisplay": {
          "kind": "amount",
          "amount": 1,
          "currency": "USD",
          "isFree": false
        },
        "bogo": null,
        "isGated": false,
        "maxPerWallet": 100,
        "maxPerTransaction": 10,
        "phaseSupply": null,
        "msUntilStart": null,
        "msUntilEnd": null
      }
    ],
    "upcoming": []
  },
  "capabilities": {
    "requiresFeatures": [
      "claim_codes",
      "nft_selection"
    ],
    "supportedBySurface": false,
    "mintUrl": "https://gravemint.io/mint/7zn5qa"
  },
  "serverTime": "2026-08-31T12:17:45.816Z"
}

Price is a shape, not a number ​

priceDisplay is the resolved display price. Use prepare when the collector is ready to mint to obtain the final wallet-specific breakdown, including fees and benefits.

kindmeaningrender
amounta settled figurethe number and its currency
rangevaries within the phase"from X"
hiddenthe creator chose to hide it until eligibledo not guess — say it is hidden
unknownno display price available for this requestdo not render 0

Show “Free” only when kind is amount and isFree is true. Keep hidden and unknown prices distinct from zero.

Eligibility ​

Server-side verdict for one wallet against one phase. Gating criteria stay on our side; you receive the decision, never the allowlist.

GET /v1/collections/:collectionId/eligibility/:phaseId/:wallet ​

js
import { GraveMintClient } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_pub_your_key" });

const eligibility = await gm.v1.eligibility("7zn5qa", "8426923e-0d64-480d-925f-90324c2dedf5", "11111111111111111111111111111111");
console.log(eligibility);
ts
import { GraveMintClient, GraveMintError, type V1Eligibility } from "@solanadeads/gravemint";

const gm = new GraveMintClient({ apiKey: "gm_pub_your_key" });

try {
  const eligibility: V1Eligibility = await gm.v1.eligibility("7zn5qa", "8426923e-0d64-480d-925f-90324c2dedf5", "11111111111111111111111111111111");
  console.log(eligibility);
} catch (err) {
  // `code` is stable — branch on it. `message` is a sentence you can show a user.
  if (err instanceof GraveMintError) console.error(err.code, err.message);
  else throw err;
}
bash
curl -s \
  -H 'X-API-Key: gm_pub_your_key' \
  'https://api.solanadeads.com/gravemint/v1/collections/7zn5qa/eligibility/8426923e-0d64-480d-925f-90324c2dedf5/11111111111111111111111111111111'
json
{
  "success": true,
  "gated": false,
  "phase": {
    "id": "8426923e-0d64-480d-925f-90324c2dedf5",
    "name": "Public",
    "startDate": "2026-03-30T16:02:00+00:00",
    "endDate": null,
    "hasStarted": true,
    "hasEnded": false
  },
  "address": "11111111111111111111111111111111",
  "message": "This phase is open to everyone — no allowlist or holder requirements."
}

Errors ​

Coded, and the code is the part you branch on. The human sentence may be reworded at any time; the code will not.

No credential at all ​

No Origin, no key. With the SDK this arrives as a thrown GraveMintError whose code is API_KEY_REQUIRED.

bash
curl -s \
  'https://api.solanadeads.com/gravemint/v1/collections/7zn5qa'
json
{
  "success": false,
  "error": "This request could not be authorised.",
  "code": "API_KEY_REQUIRED"
}

An origin we do not recognise ​

Register the requesting origin for the key. This response is distinct from a missing credential. With the SDK this arrives as a thrown GraveMintError whose code is ORIGIN_NOT_ALLOWED.

bash
curl -s \
  -H 'Origin: https://partner.example' \
  'https://api.solanadeads.com/gravemint/v1/collections/7zn5qa'
json
{
  "success": false,
  "error": "This request could not be authorised.",
  "code": "ORIGIN_NOT_ALLOWED"
}
codestatusmeaning
API_KEY_REQUIRED401no key and no recognised origin
API_KEY_INVALID401the key did not match a live record
ORIGIN_NOT_ALLOWED403the origin is not on this key
COLLECTION_NOT_IN_SCOPE403this key is not issued for that drop
AUTH_UNAVAILABLE503we could not check — retry; never treat as denial
CLIENT_BROADCAST_NOT_ALLOWED400you sent a transaction hash. See below
CHAIN_NOT_SUPPORTED_BY_SURFACE400v1 mints Solana only

Transaction submission ​

prepare-mint returns transactions for your wallet to sign. Send the signed bytes to execute-mint; GraveMint validates and submits them. A client-submitted transaction hash returns CLIENT_BROADCAST_NOT_ALLOWED.