Skip to main content

Gacha Machine API Documentation

(If you want access, join the Discord)

Overview

The gacha machine API allows users to purchase mystery packs containing NFTs, open them to receive random NFTs, and optionally sell them back for USDC. This guide covers the standard $50 pack flow.

🔐 Authentication

Each request to the API must include a valid x-api-key header.

Why It's Required

  • Ensures only authorized partners can access the machine.
  • Automatically tags your transactions with a unique memo prefix based on your API key.
  • Allows filtering and tracking all spin/win/buyback activity by your key using the slug query parameter.

Example Header

curl -X POST "https://gacha.collectorcrypt.com/api/generatePack" \
-H "Content-Type: application/json" \
-H "x-api-key: API_KEY" \
-d '{
"playerAddress": "HWPRgtDGpBm8mByTGS57BWCsijMo53qPPSbskWDukfTc"
}'

Endpoints

Transactions can be submitted directly to the blockchain after they've been signed.

1. Generate Pack - /api/generatePack

Creates a transaction for purchasing a pack. The user needs to sign this transaction to begin the purchase. Generates a partially signed transaction that transfers 50 USDC from the player to the gacha wallet. Returns a unique memo identifier and the transaction that needs to be signed by the player.

Method: POST

Request Body:

{
"playerAddress": "wallet_public_key",
"packType": "pokemon_50", // optional, defaults to "pokemon_50"; use "pokemon_250" for legendary packs
"turbo": true // optional; when true, Common wins are auto-sold during openPack
}

Response:

{
"memo": "slug-uuid",
"transaction": "base64_encoded_transaction"
}

Error Responses:

  • 400: Invalid request body or player address
  • 403: Access denied (for legendary packs without proper NFT ownership)
  • 500: Machine empty, too many packs open, or emergency stop active

Note: turbo mode will automatically process a buyback for Common wins when calling /api/openPack.


2. Generate Yolo Packs - /api/generateYoloPacks

Creates multiple transactions for purchasing multiple packs at once. Each pack gets its own transaction and memo that needs to be signed individually by the player.

Method: POST

Request Body:

{
"count": 2,
"packType": "pokemon_50",
"playerAddress": "5Kp9FbQ2oEKt6XnEvbovsnkpewW3wm9bg4ff3c3hAPbt",
"turbo": true // optional; applies to all generated packs, auto-sells Common wins during openPack
}

Response:

{
"success": true,
"packs": [
{
"memo": "slug-uuid-1",
"transaction": "base64_encoded_transaction_1"
},
{
"memo": "slug-uuid-2",
"transaction": "base64_encoded_transaction_2"
}
]
}

Error Responses:

  • 400: Invalid request body, player address, or count (max 10 packs)
  • 403: Access denied (for legendary packs without proper NFT ownership)
  • 500: Machine empty, too many packs open, or emergency stop active

What it does: Generates multiple pack purchase transactions at once. Each transaction must be signed separately using /api/submitTransaction, then each memo can be used with /api/openPack to receive the NFTs.

Note: When turbo is true, all generated packs will auto-sell Common wins during /api/openPack.


3. Open Pack - /api/openPack

Opens a purchased pack and sends an NFT to the player. Randomly selects an NFT based on rarity tiers (1% Epic, 4% High, 15% Mid, 80% Low), transfers it to the player, and returns the NFT metadata. For turbo mode with low-tier wins, automatically processes a buyback.

Method: POST

Request Body:

{
"memo": "slug-uuid-string"
}

Response (Success):

{
"success": true,
"transactionSignature": "nft_transfer_transaction_hash",
"nft_address": "nft_mint_address",
"nftWon": {
"content": {
"metadata": {
"name": "Card Name",
"description": "Card Description",
"attributes": [...]
}
}
},
"points": 0,
"rarity": ["Epic", "Rare", "Uncommon", "Common"]
}

Response (Waiting for Payment):

{
"success": true,
"code": "WAITING_FOR_WEBHOOK",
"memo": "slug-uuid-string"
}

Response (Already Opened):

{
"success": true,
"code": "NFT_SEND_EXISTS",
"transactionSignature": "existing_transaction_hash"
}

Error Responses:

  • 400: No spin transaction found or no NFTs available
  • 500: Machine empty or processing error

4. Buyback - /api/buyback

Generates a transaction to sell an NFT back for 85% of its insured value in USDC. Verifies the player won the NFT within 24 hours, then creates a transaction that transfers the NFT back to the original prize wallet and sends 85% of the insured value in USDC to the player. The transaction needs to be signed by the player and submitted to the blockchain.

Method: POST

Request Body:

{
"playerAddress": "wallet_public_key",
"nftAddress": "nft_mint_address"
}

Response:

{
"success": true,
"serializedTransaction": "base64_encoded_transaction",
"refundAmount": 42500000,
"memo": "original-memo-string"
}

Error Responses:

  • 400: Invalid addresses, NFT not found, or outside 24-hour window
  • 500: Transaction building failed

5. Buyback Check - /api/buyback/check

Checks if an NFT buyback has completed.

Method: GET

Query Parameters:

  • memo (required): The memo from the original pack purchase

Example Request:

GET /api/buyback/check?memo=953cc94e-fd51-4f5f-bbcc-5a35faf7df65

Response (Buyback Exists):

{
"exists": true,
"playerWallet": "GfFAJnHnSgP7C2FQZLz6ogpdTV6Y7259f83qFFm9wxKm",
"nft": "H9ZXYkudxn6qhyp5S25jm5SrA8Vnu8naSfvymm9TptLA",
"transactionSignature": "3Dq2kH65vqEzpBKczyDLzNYS8sXmtS5GS9MYTwjVaPM4tqVxjtPGnQG4mKpSPa5iTzqomhFgo9nYs3grRNPp68Fh",
"buybackAmount": "90000",
"createdAt": "2025-05-26T17:32:33.588Z",
"complete": "true"
}

Response (Buyback Not Found):

{
"exists": false,
"message": "No buyback transaction found for this memo"
}

Error Responses:

  • 400: Missing memo parameter
  • 500: Database query failed

What it does: Checks if a buyback transaction has been completed for the given memo. Returns the buyback details if it exists, or indicates that no buyback was found.


6. Get Status - /api/status

Checks the current operational status of the gacha machine.

Method: GET

Request: No parameters required

Response:

{
"machineStatus": "running"
}

Possible Status Values:

  • "running": Machine is operational
  • "stopped": Machine is in emergency stop mode

7. Get Stock - /api/stock

Returns the current stock counts for each rarity tier in both elite and legendary packs.

Method: GET

Response:

{
"elite": {
"common": 34,
"uncommon": 42,
"rare": 86,
"epic": 124
},
"legendary": {
"common": 98,
"uncommon": 85,
"rare": 34,
"epic": 24
}
}

What it does: Returns the number of NFTs available for each rarity in both elite and legendary packs.


8. Get NFTs - /api/getNfts

Retrieves NFTs available in the gacha machine filtered by code and optionally by rarity.

Method: GET

Query Parameters:

  • code (required): The pack/collection code (e.g., "pokemon_50")
  • rarity (optional): Filter by rarity tier - "common", "uncommon", "rare", or "epic"

Example Requests:

GET /api/getNfts?code=pokemon_50
GET /api/getNfts?code=pokemon_50&rarity=epic
GET /api/getNfts?code=pokemon_50&rarity=rare

Response:

{
"success": true,
"data": [
{
"nft_address": "nft_mint_address",
"name": "Card Name",
"description": "Card Description",
"rarity": "epic",
"attributes": [...],
"image": "image_url",
"insured_value": 50000000
}
],
"count": 10
}

Error Responses:

  • 400: Missing code parameter or invalid rarity value
  • 404: No NFTs found for the specified code/rarity combination
  • 500: Database query failed

9. Submit Transaction - /api/submitTransaction

Submits a signed transaction to the Solana blockchain.

Method: POST

Request Body:

{
"signedTransaction": "base64_encoded_signed_transaction"
}

Response (Success):

{
"success": true,
"signature": "transaction_signature_hash"
}

Example Request:

curl -X POST "/api/submitTransaction" \
-H "Content-Type: application/json" \
-H "x-api-key: API_KEY" \
-d '{
"signedTransaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQABBqF55bPp..."
}'

Error Responses:

  • 400: Missing or invalid signed transaction
  • 500: Transaction submission failed or blockchain error

What it does: Takes a fully signed transaction (from /api/generatePack or /api/openPack after user signing) and submits it to the Solana blockchain. Returns the transaction signature for tracking.


10. Generate Gift - /api/generateGift

Creates a transaction to gift packs to another wallet. The sender pays for the packs; after submitting the signed transaction, the receiver will have gifted packs available to open on gacha.collectorcrypt.com.

Method: POST

Request Body:

{
"sender": "HWPRgtDGpBm8mByTGS57BWCsijMo53qPPSbskWDukfTc",
"receiver": "daxsSgG4iPvhxWr2jrY76HKtRSjWjQLFveKHdmZKJFc",
"packType": "pokemon_50",
"count": 1
}

Response:

{
"giftId": 2,
"memo": "gift-86646f0c-2a61-4a0a-89af-495d266684c3",
"transaction": "base64_encoded_transaction",
"totalCost": 50,
"count": 1,
"packType": "pokemon_50"
}

Example Request:

curl -X POST "https://gacha.collectorcrypt.com/api/generateGift" \
-H "Content-Type: application/json" \
-d '{
"sender":"HWPRgtDGpBm8mByTGS57BWCsijMo53qPPSbskWDukfTc",
"receiver":"daxsSgG4iPvhxWr2jrY76HKtRSjWjQLFveKHdmZKJFc",
"packType":"pokemon_50",
"count":1
}'

What it does: Returns a transaction. Sign it, then POST it to /api/submitTransaction. Once confirmed, the receiver will have gifted packs to open on gacha.collectorcrypt.com.


11. Get Gifted - /api/getGifted

Fetches gift history for a wallet.

Method: GET

Query Parameters:

  • wallet (required): wallet public key
  • direction (optional): e.g. sent
  • limit (optional): e.g. 200

Example Request:

GET /api/getGifted?wallet=HWPRgtDGpBm8mByTGS57BWCsijMo53qPPSbskWDukfTc&direction=sent&limit=200

Response:

{
"wallet": "HWPRgtDGpBm8mByTGS57BWCsijMo53qPPSbskWDukfTc",
"sent": [],
"received": [],
"totals": {
"sent": [],
"received": []
}
}

12. Purchased Packs Summary - /api/purchasedPacks

Returns pack counts for a wallet (purchased vs gifted, used vs unused) grouped by packType.

Method: GET

Query Parameters:

  • wallet (required): wallet public key

Example Request:

GET /api/purchasedPacks?wallet=daxsSgG4iPvhxWr2jrY76HKtRSjWjQLFveKHdmZKJFc

Response:

{
"pokemon_50": {
"purchased": 0,
"gifted": 2,
"used_purchased": 0,
"used_gifted": 1
},
"pokemon_250": {
"purchased": 0,
"gifted": 0,
"used_purchased": 0,
"used_gifted": 0
}
}

13. Generate Purchased Pack Challenge - /api/generatePurchasedPack

Generates a message-to-sign challenge for opening a purchased/gifted pack.

Method: POST

Request Body:

{
"publicKey": "daxsSgG4iPvhxWr2jrY76HKtRSjWjQLFveKHdmZKJFc",
"packType": "pokemon_50"
}

Response:

{
"success": true,
"nonce": "89c3e1b3-9d50-4cdd-95e6-444ef3fd68e4",
"expiry": "2025-12-13T20:54:42.589Z",
"messageToSign": "Open my purchased pokemon_50 pack!\n\nNonce:89c3e1b3-9d50-4cdd-95e6-444ef3fd68e4"
}

14. Use Purchased Pack - /api/usePurchasedPack

Consumes a purchased/gifted pack after the wallet signs the challenge message. Returns a memo you can open like normal (via /api/openPack).

Method: POST

Request Body:

{
"signedMessage": "Open my purchased pokemon_50 pack!\n\nNonce:89c3e1b3-9d50-4cdd-95e6-444ef3fd68e4",
"signature": "base58_signature",
"publicKey": "daxsSgG4iPvhxWr2jrY76HKtRSjWjQLFveKHdmZKJFc",
"turbo": false,
"packType": "pokemon_50",
"nonce": "89c3e1b3-9d50-4cdd-95e6-444ef3fd68e4"
}

Response:

{
"success": true,
"memo": "cc-83f67f2e-7b53-45fd-9d81-ab4f8243475c",
"packsRemaining": 0
}

15. Get All Winners - /api/getAllWinners

Retrieves recent winners from the gacha machine.

Method: GET

Query Parameters:

  • timestamp (required): ISO 8601 timestamp to get winners after this time
  • slug (optional): Filter by memo prefix (e.g., "me")
  • epic (optional): Set to "true" to get only epic/legendary wins
  • count (optional): Number of results to return (default: 10)

Example Request:

GET /api/getAllWinners?timestamp=2024-01-01T00:00:00Z&slug=me&epic=false&count=20

Response:

{
"success": true,
"data": [
{
"winner_wallet": "wallet_address",
"nft_address": "nft_mint_address",
"prize_wallet": "prize_wallet_address",
"memo": "slug-uuid-string",
"created_at": "2024-01-01T12:00:00Z",
"nft": {
"content": {
"metadata": {
"name": "Card Name",
"attributes": [...]
}
}
}
}
]
}

Error Responses:

  • 400: Missing timestamp parameter
  • 500: Database query failed

What it does: Returns a list of recent NFT winners filtered by timestamp and optionally by memo prefix (slug) and rarity (epic). Results are ordered by most recent first.

Flow Summary

  1. Call /api/generatePack to create a purchase transaction
  2. Sign the transaction with your wallet
  3. Submit signed transaction to the blockchain
  4. Wait for confirmation
  5. Call /api/openPack with the memo to send the NFT
  6. (Optional) Call /api/buyback within 24 hours to sell the NFT back for 85% value
  7. Use /api/status to check machine availability
  8. Use /api/getAllWinners to see recent winners