Authentication

OpenSea separates application access from wallet identity.

CredentialHow it is sentUse
API keyX-API-KEYREST and MCP access and quota
SIWE sessionHTTP-only cookiesCreate, list, rotate, or revoke scoped personal access tokens (PATs)
Scoped PATBody of /api/v2/auth/tokens/exchangeMint replacement wallet JWTs without another signature
Wallet JWTAuthorization: Bearer <token>Short-lived wallet identity and scopes for REST or MCP

Public REST requests need an API key. Wallet-specific REST requests need both the API key and wallet JWT. MCP data tools follow the same rule; wallet-scoped tools need both credentials. The auth endpoints below and public scope discovery do not require an API key.

Never send a PAT in the Authorization header. Exchange it for a wallet JWT first.

CLI

Use OAuth for interactive work:

npm install -g @opensea/cli
opensea login --scopes read:favorites
opensea auth status
opensea whoami

Use SIWE when a server-side agent controls an EVM signing key:

export OPENSEA_API_KEY="..."
export OPENSEA_PRIVATE_KEY="..."
export DROP_SLUG="your-drop-slug"

opensea login --private-key --scopes read:eligibility
opensea whoami
opensea drops eligibility "$DROP_SLUG"
opensea auth revoke

The CLI keeps credentials in ~/.opensea/auth.json with file mode 0600. It does not store the private key. Run opensea auth refresh after the wallet JWT expires. See the CLI reference for commands.

SDK

OpenSeaAuth handles SIWE, PAT creation, JWT exchange, and session-authorized revocation:

import { ethers } from "ethers";
import { OpenSeaAPI, OpenSeaAuth } from "@opensea/sdk";

const privateKey = process.env.OPENSEA_PRIVATE_KEY;
if (!privateKey) throw new Error("OPENSEA_PRIVATE_KEY is required");

const signer = new ethers.Wallet(privateKey);
const auth = new OpenSeaAuth();
const token = await auth.authenticate(signer, {
  scopes: ["read:favorites"],
});

try {
  const api = new OpenSeaAPI({
    apiKey: process.env.OPENSEA_API_KEY,
    authToken: token.accessToken,
  });
  await api.walletAuth.getFavorites(await signer.getAddress(), { limit: 10 });
} finally {
  const current = await auth.getValidToken();
  await auth.revoke(current.accessToken);
}

See the @opensea/sdk reference for setup.

Manual REST flow

Use this flow if the CLI and SDK are not available:

All paths below are on https://api.opensea.io.

  1. POST /api/v2/auth/siwe/nonce to get a single-use nonce.
  2. Build and sign the exact SIWE message locally. accountType is required (Ethereum or Solana); the siwe library does not add it, and omitting it returns 400 Invalid signature even when the signature is correct.
  3. POST /api/v2/auth/siwe/verify with the parsed message, signature, and chainArch. Keep the returned session cookies.
  4. POST /api/v2/auth/tokens with the cookies, a label, the smallest useful scope set, and expiresInDays.
  5. Save the returned PAT. The server returns it only once.
  6. POST /api/v2/auth/tokens/exchange with the PAT as subjectToken and ACCESS_TOKEN as subjectTokenType.
  7. Send the returned JWT with your API key:
curl "https://api.opensea.io/api/v2/drops/example/eligibility" \
  -H "X-API-KEY: $OPENSEA_API_KEY" \
  -H "Authorization: Bearer $OPENSEA_WALLET_JWT"

PAT management is session-only. Use the SIWE session cookies with these endpoints:

MethodPathAction
GET/api/v2/auth/tokensList PATs
POST/api/v2/auth/tokensCreate a PAT
POST/api/v2/auth/tokens/{id}/rotateRotate a PAT
DELETE/api/v2/auth/tokens/{id}Revoke a PAT

A wallet JWT cannot manage PATs. Revoking or rotating a PAT stops new exchanges, but JWTs already issued from it remain valid until they expire.

MCP

Connect to https://mcp.opensea.io/mcp. Compatible clients discover OAuth from the server automatically.

MCP data tools require X-API-KEY. Wallet-scoped tools also require the wallet JWT in Authorization: Bearer. The API key supplies access and quota; the JWT supplies wallet identity and scopes.

You can connect without credentials for the handshake, tools/list, and get_instant_api_key. Add the returned API key and reconnect before calling data tools. See the MCP setup guide.

Scopes

Discover the current scopes and their REST endpoints and MCP tools:

curl "https://api.opensea.io/api/v2/auth/scopes"
opensea auth scopes

Request only the scopes needed for the task. The live OpenAPI document contains the current request fields, response schemas, and scope requirements.

Token lifecycle

CredentialLifetimeRenewal
SIWE access cookie3.5 daysRefresh with /api/v2/auth/session/refresh
SIWE refresh cookie30 daysSign in again after expiry
Scoped PATSet at creationRotate or create another PAT using the SIWE session
Wallet JWTAbout 12 hoursExchange the PAT again

Session refresh rotates the refresh cookie. Store the newest cookie values.

Errors

StatusWhat to do
401Supply or replace the API key, or refresh an expired wallet JWT once
403Request a PAT or OAuth token with the missing scope; do not retry unchanged credentials
429Wait for Retry-After before retrying

Safety

  • Keep private keys, API keys, PATs, JWTs, cookies, signatures, and full authorization headers out of prompts, logs, client-side code, and version control.
  • Keep signing keys in environment variables or a secrets manager. Do not pass them as command arguments.
  • Use a separate, minimally funded wallet for testing and request the smallest useful scope set.
  • Revoke task-specific PATs when the task is complete.
  • Require human confirmation before signing or broadcasting a spend-bearing transaction.

For API-key options and limits, see Getting Your API Key.