Troubleshooting
Use the response code to identify the condition. Messages provide context for people; codes are intended for application logic.
403 ORIGIN_NOT_ALLOWED
Check that the request's origin exactly matches one registered for the key. Include staging, local ports and preview hostnames. Wildcards are not supported; a fixed preview hostname can simplify configuration.
Browser keys also require the Origin header. For backend calls or MCP, use a server-side gm_live_ key. See keys and origins.
403 COLLECTION_NOT_IN_SCOPE
Confirm that the identifier belongs to a collection assigned to your key. The same response is used for unknown and inaccessible collections, so check for typing errors as well. A key without assigned collections has no collection access.
403 SANDBOX_KEY_ON_MAINNET / LIVE_KEY_ON_TESTNET
Match the key to the network. Use gm_test_ for test-network collections and a production key for production collections.
404 COLLECTION_NOT_FOUND on an id you know exists
Check the short ID, UUID or on-chain address and confirm the collection is available through your key. Preserve address case. If using an older API deployment, verify its supported identifiers against the SDK version.
The price is wrong, or shows 0
Read priceDisplay and handle all four kind values. Show “Free” only for kind: 'amount' with isFree: true. A pegged display price can be approximate. Use peggedPrice(phaseId) to refresh it; v1 phases do not expose a raw price field. See pricing.
“Mints remaining” differs between responses
Use walletMints for minted and remaining counts. It includes bonus mints; eligibility evaluates allocations with different counting rules. Refresh wallet data after a mint.
CLIENT_BROADCAST_NOT_ALLOWED
Send the signed transaction bytes as signedTransaction. GraveMint submits the transaction; execute does not accept a client-submitted transactionHash. See wallets and signing.
TX_MODIFIED
The signed transaction differs from the prepared transaction. Check that the wallet adapter only signs the supplied bytes and does not add instructions or change accounts. Do not resubmit the same modified transaction. Correct the adapter and prepare a new session.
SESSION_EXPIRED, or a mint that 409s
An expired session needs a fresh prepare. A conflict such as ALREADY_PROCESSING or ALREADY_COMPLETED requires checking the existing session's outcome before starting another mint. Keep these cases separate: a request that is already processing may still complete.
Batch result handling
mint() can return a partial batch outcome without throwing. Inspect results[], including each transaction's errorCode and pending state. With executeBatch(), top-level success means at least one transaction succeeded; it does not mean all succeeded.
const result = await gm.mint.mint({ collectionId, phaseId, walletAddress, quantity, signer });
if (result.results) {
for (const transaction of result.results) {
if (transaction.pending) {
// Retain transaction.sessionId and check the wallet before retrying.
} else if (!transaction.success) {
// Display transaction.error and handle transaction.errorCode.
}
}
}For MintOutcomeUnknownError / OUTCOME_UNKNOWN, retain sessionIds and check the wallet. Do not automatically submit a new mint while the outcome remains uncertain.
429, or mints are throttled
Honor Retry-After and review the rate limits. Prepare and execute share a per-key limit, and prepares also use a collection limit shared with the hosted site.
The SDK retries eligible read requests with backoff. Execute calls are not retried automatically by default, because the original transaction may already have been submitted. See SDK retries.
503 AUTH_UNAVAILABLE
The authentication service could not complete the key check. Retry with backoff; this response does not mean the key is invalid. LOOKUP_FAILED similarly indicates that a collection lookup could not complete.
Browser CORS errors
Inspect the preflight (OPTIONS) response in the network panel. If the browser rejects that response, it will not send the subsequent API request. A 204 status alone is insufficient: check that Access-Control-Allow-Origin matches the requesting origin and that the requested headers and method are allowed.
Still stuck
Include the error code, key prefix (gm_pub_, gm_live_ or gm_test_), origin, collection identifier and SDK version when contacting support. Include a sanitized response where useful. Do not send the full key.
