Mint from a drop programmatically
Build a custom mint experience using the OpenSea Drops API.
The OpenSea Drops API lets you discover active drops, check eligibility, and mint NFTs programmatically. This is the buyer/minter side. If you want to create and manage a drop as a creator, see Create a primary drop.
Prerequisites
- Node.js >= 20.0.0
- OpenSea API key (get one here, or use the instant API key endpoint)
- viem (v2+). ethers.js (v6+) is also supported.
- A funded wallet on the drop's chain
Security Warning: Do not use the SDK in client-side code, since your API key would be exposed. Use it on a backend server and return transaction data to your frontend.
Setup
npm install @opensea/sdk viemimport { createPublicClient, createWalletClient, http } from "viem";
import { base } from "viem/chains";
import { OpenSeaSDK, Chain } from "@opensea/sdk/viem";
const publicClient = createPublicClient({ chain: base, transport: http("https://your-rpc-url") });
const walletClient = createWalletClient({ chain: base, transport: http("https://your-rpc-url"), account: "0x..." });
const sdk = new OpenSeaSDK(
{ publicClient, walletClient },
{ chain: Chain.Base, apiKey: "YOUR_API_KEY" },
);The examples below use viem. The SDK also supports ethers.js (v6+); see Buy and sell NFTs for the ethers setup. All SDK methods work the same with either library.
Step 1: discover available drops
Browse drops by type: featured, upcoming, or recently_minted.
SDK
// Featured drops
const featured = await sdk.api.drops.getDrops({ type: "featured" });
// Upcoming drops
const upcoming = await sdk.api.drops.getDrops({ type: "upcoming" });
// Recently minted
const recent = await sdk.api.drops.getDrops({ type: "recently_minted" });
for (const drop of featured.drops) {
console.log(drop.collectionSlug, drop.collectionName);
}curl
# Featured drops
curl -X GET "https://api.opensea.io/api/v2/drops?type=featured&limit=20" \
-H "X-API-KEY: YOUR_API_KEY"
# Upcoming drops
curl -X GET "https://api.opensea.io/api/v2/drops?type=upcoming&limit=20" \
-H "X-API-KEY: YOUR_API_KEY"You can filter by chain:
curl -X GET "https://api.opensea.io/api/v2/drops?type=featured&chains=base&limit=20" \
-H "X-API-KEY: YOUR_API_KEY"Step 2: get drop details
Fetch full details for a specific drop including mint stages, pricing, supply, and allowlists.
SDK
const drop = await sdk.api.drops.getDrop("my-collection-slug");
console.log("Name:", drop.collectionName);
console.log("Minted:", drop.totalSupply);
console.log("Max supply:", drop.maxSupply);
console.log("Stages:", drop.stages);
// Each stage includes: label (e.g. "Allowlist", "Public"),
// price, startTime and endTime, and maxPerWalletcurl
curl -X GET "https://api.opensea.io/api/v2/drops/my-collection-slug" \
-H "X-API-KEY: YOUR_API_KEY"Step 3: check stages and supply
The drop details response includes each stage's price, timing, and per-wallet limit. Inspect the stages and remaining supply before you mint. To check whether a specific wallet is eligible, call GET /api/v2/drops/{slug}/eligibility, which needs a wallet token with the read:eligibility scope (see Authentication).
const drop = await sdk.api.drops.getDrop("my-collection-slug");
for (const stage of drop.stages) {
console.log(`Stage: ${stage.label}`);
console.log(` Price: ${stage.price}`);
console.log(` Max per wallet: ${stage.maxPerWallet}`);
console.log(` Start: ${stage.startTime}`);
console.log(` End: ${stage.endTime}`);
}
// Check remaining supply (maxSupply and totalSupply are decimal strings)
const remaining = Number(drop.maxSupply) - Number(drop.totalSupply);
console.log("Remaining supply:", remaining);Step 4: build the mint transaction
Generate the transaction data to mint NFTs from the drop.
SDK
const mintTx = await sdk.api.drops.buildMintTransaction("my-collection-slug", {
minter: "0xYOUR_WALLET_ADDRESS",
quantity: 2,
});
console.log("Contract:", mintTx.to);
console.log("Data:", mintTx.data);
console.log("Value (wei):", mintTx.value);
console.log("Chain:", mintTx.chain);curl
curl -X POST "https://api.opensea.io/api/v2/drops/my-collection-slug/mint" \
-H "X-API-KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"minter": "0xYOUR_WALLET_ADDRESS",
"quantity": 2
}'The response contains:
| Field | Description |
|---|---|
to | The contract address to call |
data | Hex-encoded transaction data |
value | Native token value to send (mint price in wei), as a decimal string |
chain | The chain to send the transaction on, as an OpenSea chain slug such as base |
stage_uuid | The stage the transaction was built for. It matches a uuid in the drop's stages, unless the stage is hidden. Absent if the stage could not be determined |
stage_type | That stage's type, as in the drop's stages |
stage_start_time, stage_end_time | That stage's start and end times (ISO 8601) |
to, data, and value map directly onto the fields of a transaction request. Convert value with BigInt() before you send it, as the next step does.
A presale transaction carries its stage's start and end times in its signed parameters and reverts if it is mined outside them, so send it before stage_end_time.
Step 5: execute the mint
Submit the transaction onchain using the data from the previous step.
import type { Address, Hex } from "viem";
const hash = await walletClient.sendTransaction({
to: mintTx.to as Address,
data: mintTx.data as Hex,
value: BigInt(mintTx.value),
});
console.log("Transaction hash:", hash);
const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log("Minted! Block:", receipt.blockNumber);Full example
Putting it all together: discover a drop, check supply, and mint.
import { createPublicClient, createWalletClient, http, type Address, type Hex } from "viem";
import { base } from "viem/chains";
import { OpenSeaSDK, Chain } from "@opensea/sdk/viem";
const publicClient = createPublicClient({ chain: base, transport: http("https://your-rpc-url") });
const walletClient = createWalletClient({ chain: base, transport: http("https://your-rpc-url"), account: "0x..." });
const sdk = new OpenSeaSDK(
{ publicClient, walletClient },
{ chain: Chain.Base, apiKey: "YOUR_API_KEY" },
);
const COLLECTION_SLUG = "my-collection-slug";
const WALLET = "0xYOUR_WALLET_ADDRESS";
const QUANTITY = 1;
// Check drop details
const drop = await sdk.api.drops.getDrop(COLLECTION_SLUG);
const remaining = Number(drop.maxSupply) - Number(drop.totalSupply);
console.log(`${drop.collectionName}: ${remaining} remaining`);
if (remaining < QUANTITY) {
console.log("Not enough supply remaining");
process.exit(1);
}
// Build and execute mint transaction
const mintTx = await sdk.api.drops.buildMintTransaction(COLLECTION_SLUG, {
minter: WALLET,
quantity: QUANTITY,
});
const hash = await walletClient.sendTransaction({
to: mintTx.to as Address,
data: mintTx.data as Hex,
value: BigInt(mintTx.value),
});
const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log("Minted! Tx:", receipt.transactionHash);Next steps
- Create a primary drop: set up a drop as a creator
- Display an NFT: show minted NFTs on a website
- Query analytics and events: track minting activity
- Drops API reference
- @opensea/sdk on GitHub
Updated 4 days ago