- b68b01e: Add typed order-action APIs for creating offers, fulfilling listings and offers, and cancelling orders across EVM chains and Solana.
-
b2b07f2: Cancel the rate-limit retry delay when the caller's
AbortSignalfiresRequestOptions.signalreached each fetch attempt but not the wait between them, so aborting during a 429/599 backoff left the promise pending for the fullRetry-After(capped at five minutes) and then started another attempt.getandrequestnow pass the signal into the retry layer, which rejects with the existingRequest abortederror and does not retry. -
b2b07f2: Preserve signed multipart field names in wallet-auth upload contexts
The four helpers that return an
UploadContext(createProfileImageUpload,createCollectionImageUpload,createDropAllowlistUpload,createDropItemMediaUpload) no longer camelize their response.fieldsis an opaque signed field map that the caller must submit unchanged, so a legitimate S3 policy field such assuccess_action_statuswas being returned assuccessActionStatusand the resulting form no longer matched the signed policy. -
Updated dependencies [ed91bb6]
- @opensea/api-types@0.8.11
-
bbbbfea: Pin the wire shape of the agent handshake bodies.
proposeAgentRelationshipandconfirmAgentRelationshiptake camelCase, like every other default-path write, andFetcher.requestconverts to the snake_case the API requires. That was already the behavior, but nothing tested it end to end: the existing specs stub the fetcher, so they show the body being handed straight torequestand never show the conversion. Reading the method alone, a caller can reasonably conclude they must supply{counterparty_address, caller_role}themselves, and the API answers a camelCase body with 400 "Missing required field 'counterparty_address'", which does not name the real problem.The new test drives the real fetcher and asserts the exact bytes. No behavior change.
-
34d3a50:
cancelOrdersno longer rejects a batch whose orders name the same Seaport protocol address in different letter cases. The addresses were grouped in aSetkeyed on the raw string, so one protocol counted as several. Thanks to @Mabolla (#1999). -
34d3a50: Providers: infer the EIP-712 primary type as the root of the type graph instead of taking the first key in
types. Both the viem adapter and the seaport bridge signed the wrong struct when a dependency was declared before the root, and neither refused an ambiguous or circular type set. Both now share one helper and throw rather than guess, matching what ethers does with the same input. Thanks to @Mabolla (#1998, #2000). -
3cc8640: The wire-shape guard added in #646 observes which
input_datakeys the ERC20 preflight reads by handing it a recording Proxy. That Proxy only had agettrap, so a refactor toObject.keys(inputData)or anintest would have reached a key without the guard seeing it. It now trapsownKeysandhastoo.Tests only, no behaviour change.
-
ea967e2: The ERC20 fulfillment preflight is now tested against captured
POST /api/v2/listings/fulfillment_dataresponses rather than a hand-written guess at their shape. Four response bodies are committed verbatim, covering both call shapes a single-listing fulfillment can return and both an ERC20-priced and a native-priced form of each, and the expected payment total comes from the listing price a separate endpoint reports.A new
erc20FulfillmentWireShapesuite checks every top-levelinput_datakey the preflight reads against theinput_datavariants declared in the OpenAPI spec, so a name the API does not send has to be justified as a deliberate alias instead of silently disabling the guard, which is what shipped in #638.No behaviour change and no change to the public API. The keys the check inspects are observed at runtime through a recording Proxy rather than read out of the source text, so a rename or an extracted helper cannot quietly narrow what gets checked.
-
75aa2c2: Breaking: removes the retired wallet-level agent designation.
SDK:
WalletAuthAPI.markWalletAsAgentandWalletAuthAPI.removeWalletAgentDesignationare gone. CLI:opensea accounts mark-agentandopensea accounts remove-agent, along withclient.accounts.markAgentandclient.accounts.removeAgentonOpenSeaCLI.The endpoints they called,
PUTandDELETE /api/v2/accounts/wallets/{wallet}/agent, no longer exist. os2-core removed them in ProjectOpenSea/os2-core#52946: over the 7 days before that, everyPUTwas rejected with 403 by a kill switch and no wallet's agent flag changed at all. Keeping the methods would mean shipping calls that 404.An agent is an account, not a flag on a wallet. Use
declareAgentAccount,withdrawAgentAccountDeclaration, and theproposeAgentRelationship/confirmAgentRelationship/revokeAgentRelationshiphandshake, or theopensea agentcommand group. Both are unchanged by this release.WalletAgentStatusResponseis no longer re-exported from the CLI'stypes/api, since the schema goes away with the next spec sync.
-
6c0ee99: Add SDK and CLI support for agent accounts, so an agent can declare itself and complete the ownership handshake without hand-rolling HTTP.
An agent is an account, not a flag on a wallet. Ownership is a relationship between two accounts, mutually confirmed. It is a declaration, not an authorization: naming an account as your agent grants it no ability to act for you. It is self-reported and OpenSea does not verify it. An agent can have no owner at all, and at most one confirmed owner. Either side may withdraw or revoke at any time, which deletes the relationship. Only confirmed relationships are public.
SDK, on
WalletAuthAPI:declareAgentAccount,withdrawAgentAccountDeclaration,proposeAgentRelationship,confirmAgentRelationship,revokeAgentRelationship, andlistOwnAgentRelationships.AccountsAPI.getAgentProfileRelationshipsalready covered the public read.CLI, a new
agentgroup:declare,withdraw,propose,confirm,revoke,list, andprofile, plus a matchingclient.agentnamespace onOpenSeaCLI.The scopes differ, which is easy to get wrong. Every write takes
write:walletsbut listing your own relationships takesread:wallets, so a client driving the whole handshake must request both or the list call returns 403.read:walletsis now inOPENSEA_SCOPES, so the default OAuth grant carries it.The OpenAPI snapshot is refreshed to generate all of this. That also picks up
read:walletsinAuthScope, which was already live in the scope registry but missing from the committed snapshot, soscripts/check-auth-scope-drift.mjswas failing on main beforehand.AgentProfileRelationshipsResponseno longer surfacesagent_owner_profileorpublic_agent_wallets. Both read the retired wallet-level designation, are permanently null and empty, and are removed by os2-core AGE-51. ReadagentOwnerandagentsinstead.markWalletAsAgentandremoveWalletAgentDesignationare deprecated. They set a flag on a wallet rather than declaring an account, and the server now rejects new designations; only the removal still works, so an account that set the old flag can clear it.
-
ddadb41: Replace five hand-rolled API types with the generated ones from
@opensea/api-types.packages/cli/AGENTS.mdandpackages/api-types/AGENTS.mdboth say never to hand-roll API request or response types, but these five predate the rule and duplicated schemas the spec already covered.In the SDK:
GetChainsResponsebecomesCamelize<ChainListResponse>,DropMintRequestandDropMintResponsebecomeCamelize<>of the identically named generated schemas,ResolveAccountResponsebecomesCamelize<AccountResolveResponse>, andValidateMetadataResponsebecomesCamelize<>of the generated schema, which decomposes intoValidateMetadataAssetIdentifier,ValidateMetadataDetails,ValidateMetadataAttributeandMetadataIngestionError. In the CLI:ValidateMetadataResponsebecomes aSchemas[...]re-export, the one declared violation in a file that is otherwise all re-exports.No shape change. Each replacement was diffed field by field against the spec, including required and optional, and they match exactly, so this is types-only with no runtime or behavioral effect. Four of the five were already correct re-exports in the CLI and hand-rolled only in the SDK, so the two packages had disagreed about the same names.
-
cfbb465:
onItemReceivedOfferis now a no-op. The Stream API does not emititem_received_offerand never has, so the method only ever registered a handler that could not fire. Confirmed against production: four minutes oncollection:*delivered 736k events across ten event names and this was not among them, while every other type appeared within 1.8s.Item-level offers arrive as
item_received_bid, which carries an identical payload. UseonItemReceivedBid.The method stays callable so existing code compiles and runs unchanged, and it no longer opens a connection for a topic that yields nothing.
EventType.ITEM_RECEIVED_OFFER,ItemReceivedOfferEvent, andItemReceivedOfferEventPayloadare kept for source compatibility but marked deprecated and hidden from the generated docs. -
6e77b5e:
fulfillOrdernow appends the attribution suffix the fulfillment endpoints return, so fills built by the SDK are attributed to OpenSea onchain. They were not before: the API returnscalldata_suffix(the first four bytes ofkeccak256("api.opensea.io")) and carries it as trailing calldata on its own transactions, but the SDK re-encodes the call frominput_dataand signed that instead, which dropped it. Seaport reads its arguments from offsets and ignores trailing bytes, so the suffix does not affect execution. A missing or malformed suffix is ignored rather than raised.Private listings are unaffected. They are fulfilled locally through seaport-js and never receive API calldata, so there is no suffix to re-attach.
fulfillPrivateOrderalready takes adomainfor that purpose;fulfillOrderneither accepts nor forwards one, so private fills through it stay unattributed.FulfillmentDataResponseis now derived from@opensea/api-typesinstead of hand-rolled. It had drifted: nocalldataSuffix, novalueHex, fourinputDatamembers against the spec's seven, and a basic-order member namedbasicOrderParameterswhere the API sendsparameters, so that branch never matched and the fallback built the arguments instead. Same result for a single-field struct, so no behavior change there. -
f74c0be: Deduplicate Stream API payload types and logging internals without changing the public API.
-
Updated dependencies [5fdac00]
- @opensea/api-types@0.8.10
-
d355093: Three fixes from community reports on the public mirror, each of which changes behavior for input that previously produced a wrong answer or an unhelpful crash.
getTraitsno longer camelizes its response. The fetcher rewrites every response's keys from snake_case to camelCase, which is right for the spec-derived endpoints and wrong for this one: its keys are the collection's own trait names and trait values. Afur_colortrait was reported asfurColor, and a collection with bothdark_brownanddarkBrownvalues had them merged into one entry whose count was wrong, with nothing in the response to indicate it.RequestOptionsgains acamelizeResponseopt-out, honored by both reads and writes, andgetTraitsis the only caller that sets it. If you have been reading camelized trait keys since 11.0.0, they now come back as the collection authored them. (#1989)parseUnitsaccepts scientific notation from strings. It only stripped exponent notation when the value was anumber, soparseUnits("1e-8", 18)reachedBigIntintact and threwCannot convert 1e-8000000000000000000 to a BigInt. Any caller that stringifies an amount first hit this, including the SDK's ownwrapEth,unwrapWeth, and listing/offer price paths, which all callamount.toString(). Expansion is now done with string math rather thanNumber.prototype.toFixed, so large values stay exact (toFixedcorrupts above 2^53 and returns exponential notation again at or above 1e21) and a value below the token's precision throwsToo many decimal placesrather than silently truncating to zero. Malformed input now throwsInvalid decimal valueinstead of a rawSyntaxErrorfromBigInt, and an empty string throws rather than parsing as0. (#1990)Private listings reject payment items in different tokens.
constructPrivateListingCounterOrderchecked that every payment item shared anitemTypebut not that they shared a token, then summed them into a single offer item denominated in the first item's token: 100 TOKEN_A plus 20 TOKEN_B became 120 TOKEN_A. Seaport rejected the resulting match, so the failure surfaced as an onchain revert instead of an SDK error. Token comparison is case-insensitive, so the same address in checksummed and lowercase form is still one currency. (#1991) -
8527112: Add the OpenSea Stream API client at the
@opensea/sdk/streamsubpath, replacing the standalone@opensea/stream-jspackage.The client speaks the Phoenix Channels wire protocol directly instead of depending on
phoenix, so the subpath resolves to six local files and no third-party runtime code. Importing it pulls in neither ethers nor seaport. The transport sits behind an internal interface so a future Stream API v2, which will not use Phoenix framing, can be added without a breaking change.Migrating from
@opensea/stream-jsis mostly an import change. SeedeveloperDocs/stream-migration.md.- Node users no longer need
wsornode-localstorage. Node 22+ and browsers supply a globalWebSocket, andsessionStoragewas only read by an unused long-poll fallback. apiKeyreplacestokeninClientConfig.tokenstill works and is deprecated.connectOptionsis nowStreamConnectOptionsrather thanPartial<SocketConnectOption>from@types/phoenix. Options that only fed the long-poll fallback and binary serializer are gone.- Unsubscribing now removes a single handler instead of leaving the whole collection channel. Previously, two subscriptions on one collection meant unsubscribing from one silently stopped the other.
engines.nodeis raised to>=22.0.0. Node 20 reached end of life in April 2026.
- Node users no longer need
-
8715ac2: Point the package metadata at the renamed public repo,
ProjectOpenSea/opensea-sdk.repository.urlandbugs.urlboth moved, so the npm page links to the right place rather than relying on GitHub's rename redirect. The npm package name is unchanged.Also drops the TypeDoc setup that fed the GitHub Pages site at
projectopensea.github.io/opensea-js. Nothing published it: no workflow built thegh-pagesbranch, so the site had been serving v8.0.20 docs against a shipped 11.8.0 for months. Thedocs-buildanddocs-build-mdscripts, thetypedocandtypedoc-plugin-markdowndevDependencies, and.config/typedoc.jsonare gone, along with the dead Coveralls badge (that project returns 403 and no CI job has uploaded coverage in a long time). Method-level reference docs live indeveloperDocs/api-reference.md.
- 59f9799: Check the payment token before fulfilling an ERC20-denominated listing.
fulfillOrdernow reads the buyer's balance and their allowance for the address Seaport pulls the payment through (the conduit registered for the fulfiller conduit key, or Seaport itself when that key isbytes32(0)), and throws an error naming the spender and the exactapproveamount instead of letting the transaction revert with a bare "execution reverted". Native-priced listings and offer fulfillments are unaffected, and an unreadable response shape or a failed RPC read skips the check rather than blocking the purchase.
-
c5e2906:
createListingAndValidateOnchain(),createOfferAndValidateOnchain(),buildListingOrderComponents()andbuildOfferOrderComponents()no longer request an EIP-712 signature. They built the order by running seaport-jsexecuteAllActions(), which signs, and then discarded the signature before validating the order onchain. Callers got a wallet signature prompt for nothing, and contract accounts that cannot produce an offchain signature could not use the onchain path at all, which is the case it exists for. Token approvals still run, and each is confirmed before the order is validated.validateOrderOnchain()takes an optional thirdprotocolAddressargument and rejects a protocol OpenSea does not support, matchingapproveOrder()and the fulfillment methods.Requires
@opensea/seaport-js4.2.0, which adds theexecuteApprovals()andorderComponentsAPIs this relies on.
- 4dd7c67:
cancelOrder()now returns the cancellation transaction hash, matchingcancelOrders(). The hash was computed internally and discarded, so callers had no way to track a single-order cancellation. Thanks to @Sertug17 for the fix (opensea-js#1982). - 280acf2: Fix
WalletAuthAPI.linkWallet()sending a snake_cased request body.link_wallet_with_siwxis camelCase on the wire andchainArchis required, so the default conversion renamed it tochain_archand the call failed validation every time. The nested SIWXmessagekeys were being renamed too, which the server needs intact to rebuild the message the wallet signed. Thanks to @crazywriter1 for the fix (opensea-js#1988). - Updated dependencies [d88963f]
- @opensea/api-types@0.8.8
-
23a3772: Fix the wallet-auth casing test failing on the public
opensea-jsmirrorThe spec-derived tripwire added in 11.7.1 located
opensea-api.jsonatpackages/api-types/opensea-api.json, which only exists inside the devtools monorepo. On the public mirror the SDK is synced standalone and@opensea/api-typesis an ordinary npm dependency, so the lookup threw and failednpm testduring the publish workflow — blocking the 11.7.1 npm release.It now resolves
node_modules/@opensea/api-types/opensea-api.jsonfirst, the one path present in both layouts (a workspace symlink in the monorepo, the installed package on the mirror), keeping the monorepo paths as a fallback. No change to what the test asserts.
-
0031eed: Add SDK and CLI support for wallet visibility and agent profile relationships
@opensea/sdk: addWalletAuthAPI.makeWalletPrivate,WalletAuthAPI.makeWalletPublic, andWalletAuthAPI.getAgentProfileRelationships.@opensea/sdk: exportWalletVisibilityResponse,AgentProfileRelationshipsResponse,SvmInstructionAccountResponse,SvmInstructionResponse, andSvmTransactionDetailsResponsetypes.@opensea/cli: addaccounts make-private,accounts make-public, andaccounts agent-relationshipscommands.@opensea/cli: export the new wallet visibility, agent relationship, and SVM transaction detail types.
-
7d2dbef: Sync OpenAPI spec: add
stablechaintoChainIdentifier, addChain.StableChain(chain id 988) to the SDK and generated chain maps -
f67fbc6: Fix wallet-auth writes corrupting camelCase request bodies
Fetcher.requestsnake_cases every body by default, but four wallet-auth endpoints declare camelCase properties in their OpenAPI schemas. Those calls were being sent with keys the server doesn't recognise:setProfileNftPfp—contractAddressandtokenIdare required, so the call always failed validation. It could never succeed.createProfileImageUpload—imageTypeandcontentTypeare required, so this always failed too.updateProfileSettings— all fields optional, so the request returned 200 while silently discardingdisplayName,externalUrl,profileImageToken, andbannerImageToken. Onlybioworked, because it's a single word with no casing to mangle.cancelOrder—offererSignaturewas silently dropped, turning a signed cancel into an unsigned one.
All four now send the body verbatim via
snakeizeBody: false, the same opt-out the Seaport order and offer helpers already use. Endpoints whose wire format really is snake_case are unchanged. -
Updated dependencies [7d2dbef]
-
Updated dependencies [8b7ddd2]
-
Updated dependencies [0031eed]
- @opensea/api-types@0.8.7
- a093a89: Add first-class SDK and CLI access to materialized token activity stats, with typed window selection and response models.
- 954d547: Add typed account agent status fields and helpers to mark or clear registered agent wallets from the SDK and CLI.
- Updated dependencies [954d547]
- @opensea/api-types@0.8.6
- cba26dd: Add typed SDK and CLI support for building cross-chain drop mint transactions and polling the returned receipt request.
- Updated dependencies [cba26dd]
- @opensea/api-types@0.8.4
- 8df1f43: Require the collection image MIME type in
walletAuth.createCollectionImageUploadand allow body-lesswalletAuth.cancelOrdercalls when no offerer signature is needed. - 14fcba5: Add
walletAuth.setProfileNftPfpandwalletAuth.clearProfileNftPfphelpers for the newPOST/DELETE /api/v2/profile/nft-pfpendpoints, letting an authenticated wallet set or clear an owned NFT as its profile picture.
- bf5874d: Add
getAccountTokenActivitytoTokensAPIandOpenSeaAPIforGET /api/v2/account/{address}/token-activity. DeriveContract,TokenBalance,GetTrendingTokensResponse,GetTopTokensResponse,GetAccountTokensResponse,CollectionSearchResult,TokenSearchResult,NftSearchResult,AccountSearchResult,SearchResult, andSearchResponsefrom@opensea/api-typesschemas with nullable-field overrides where the live API returnsnullfor optional fields. - bf5874d: Update
TokenandGetTokenResponseto derive from the OpenAPITokenResponseandTokenDetailedResponseschemas, exposing new fields includingusdPrice,isVerified,marketCapUsd,volume24h,priceChange24h,holdersCount,createdAt,genesisDate,description,stats,socials, andstatus.
- 9bc9708: Require explicit scopes for private-key CLI login, and add typed SDK helpers for the wallet-authenticated social and saved-tools REST endpoints.
- 06e96e1: Use the current SIWE session, scoped-token creation, token-exchange, session refresh, and session-only revocation endpoints in the SDK and CLI.
- feb1446: Sync OpenAPI spec: add
/api/v2/saved-tools(GET/POST/DELETE) beta endpoints andread:tools/write:toolsauth scopes, new saved-tool schemas, and additive token fields (is_verified,holders_count,created_at,genesis_date,description_source,subreddit_identifier). AddsOPENSEA_SCOPES.READ_TOOLS/WRITE_TOOLSto the SDK. - Updated dependencies [feb1446]
- @opensea/api-types@0.8.2
- fa2a24e: Add the canonical
read:socialandwrite:socialwallet-auth scopes. - Updated dependencies [66396b6]
- Updated dependencies [fa2a24e]
- Updated dependencies [333104e]
- Updated dependencies [d7a44df]
- @opensea/api-types@0.8.1
- b6abc18: Reject explicit empty OAuth scope lists to prevent the authorization server from expanding them to every account role.
- a410930: Request Zitadel's role-specific scopes so OAuth tokens are limited to the OpenSea scopes the client asked for.
- d10626b: Add an
opensea whoamicommand that displays the current wallet identity, scope source, and expiry, with unverified JWT diagnostics available through an explicit flag. Expose whether OAuth scopes came from the authorization-server response or a JWT fallback.
- d846160: Use the current OpenSea API endpoints for SIWE login, scoped-token exchange, refresh, revocation, and wallet-link nonces.
- b64a4d5: Require complete OAuth wallet sessions, retain refresh tokens during rotation, validate the CLI auth store, and preserve case-sensitive wallet addresses.
- 5966017: Keep the default SDK test suite offline by blocking unmocked network requests and running live API and RPC checks through the integration suite.
- 71ae9ee: Keep OAuth scope status aligned with the OpenAPI scope catalog when the token endpoint omits its
scopefield.
- df2b152: Add SIWX wallet-link helpers for nonce, message, and link flows.
- 4bef9a5: Add typed
api.walletAuthhelpers for all 29 scoped wallet operations.
- 2459068: Align wallet-auth scope metadata with the production OpenAPI specification.
- 0df96eb: Enable Seaport support for Robinhood chain. Canonical Seaport 1.6 is deployed on Robinhood (chain id 4663) and configured in the marketplace backend, so the payment-token helpers no longer throw for it: offers use WETH
0x0bd7d308f8e1639fab988df18a8011f41eacad73, listings use native ETH, and the chain uses the same default conduit as Abstract, HyperEVM, and Monad. - Updated dependencies [df2b152]
- Updated dependencies [2459068]
- Updated dependencies [4bef9a5]
- @opensea/api-types@0.8.0
- df2b152: Add public SIWX wallet-link support for agents: export nonce generation, message signing, and wallet-link verification helpers (
generateSiwxNonce,generateSiwxMessage, andverifyWalletLinkfunctions) fromsrc/auth/siwx.tsfor integrating keyless wallet-link flows in autonomous agent environments.
- 0df96eb: Enable Seaport support for Robinhood chain (4663): canonical Seaport 1.6 is now configured for Robinhood, enabling payment-token helpers and offer/listing generation. Robinhood uses WETH
0x0bd7d308f8e1639fab988df18a8011f41eacad73for offers, native ETH for listings, and the same default conduit as Abstract, HyperEVM, and Monad. - ba30caf: Fix
parseUnitsto correctly handle string inputs with scientific notation (e.g.,"1e-8","1E6"). Previously only number-type values were normalized, causing SyntaxError for string scientific notation. Fixes #1978. - Updated dependencies [df2b152]
- @opensea/api-types@0.7.0
- ef89be8: Add SIWE authentication helpers:
OpenSeaAuthclass with authenticate, getValidToken, and revoke methods. SupportauthTokenandauthBaseUrlinOpenSeaAPIConfigfor wallet-authenticated endpoints. - e61a57c: Add
OpenSeaOAuthOAuth 2.1 helper (authorization-code + PKCE, device authorization grant, refresh, and revoke) for keyless login against the OpenSea authorization server. ExposesOpenSeaOAuthConfig,OAuthToken, and related types, plus adecodeJwtPayloadutility for reading token claims. - ef89be8: Add
OPENSEA_SCOPES,OpenSeaScope, andALL_SCOPESexports — scope constants derived from the OpenAPI spec'sAuthScopeschema (via@opensea/api-types), with compile-time assertions that fail the build if they drift from the spec. - c460fc1: Add wallet trading P&L methods to
OpenSeaAPI:getWalletPnl,getWalletClosedPositions, andgetWalletTokenTransfers, with camelizedWalletPnlResponse,ClosedPositionsResponse, andPositionTokenTransfersResponsetypes plusWalletClosedPositionsArgs/WalletTokenTransfersArgsquery args.
- b816727: Add missing chain payment-token mappings for Soneium and AnimeChain, and make Solana/Hyperliquid fail fast with clear unsupported-chain errors for OpenSea Seaport offer/listing helpers. This fixes the chain helper drift tracked in #1975.
- c9d8cb1: Recreate the community fixes from #1974 and #1976: validate
amountbeforeparseUnitsin_getPriceParameters, and rejectcancelOrdersbatches that mix protocol addresses. Also add a runtime chain-helper exhaustiveness guard so newChainvalues are consciously categorized. - e59df7f: Sync OpenAPI spec: add tool activity endpoint,
robinhoodchain,source/collectionsearch filters,calldata_suffixon fulfillment, SIWX wallet-link endpoint (POST /api/v2/accounts/wallets/siwxwithLinkWalletSiwxRequest/WalletLinkResponse), re-publishedGET /api/v2/account/{address}/favorites, and the newwrite:walletsauth scope (also added to the SDK'sOPENSEA_SCOPES) - Updated dependencies [e59df7f]
- Updated dependencies [c460fc1]
- Updated dependencies [ef89be8]
- @opensea/api-types@0.6.0
- Updated dependencies
- @opensea/api-types@0.5.0
- fix: correct
GetSwapQuoteArgsto match the swap quote endpoint.getSwapQuotenow takes{ fromChain, fromAddress, toChain, toAddress, quantity, address, slippage?, recipient? }, matchingGET /api/v2/swap/quote(the previous{ tokenIn, tokenOut, amount, chain }shape did not map to the endpoint's query params).
-
8fa9fb5: Expose the new
token/{chain}/{address}/holdersandtoken/{chain}/{address}/liquidity-poolsendpoints across SDK, CLI, and skill.OpenSeaAPI.getTokenHolders(chain, address, args?)→TokenHoldersResponse— paginated holders (limit,cursor,sortBy: "QUANTITY",sortDirection) plus aggregate distribution health (STRONG | HEALTHY | CONCERNING | BAD).OpenSeaAPI.getTokenLiquidityPools(chain, address, args?)→TokenLiquidityPoolsResponse— pools with pool type, USD reserves, bonding-curve progress, graduation flag.- New type exports:
TokenHoldersResponse,TokenHoldersArgs,TokenLiquidityPoolsResponse,TokenLiquidityPoolsArgs. - New path helpers in
apiPaths.ts:getTokenHoldersPath,getTokenLiquidityPoolsPath.
opensea tokens holders <chain> <address> [--limit] [--next] [--sort-by] [--sort-direction]opensea tokens liquidity-pools <chain> <address> [--limit]- SDK class additions:
OpenSeaCLI.tokens.holders(...),OpenSeaCLI.tokens.liquidityPools(...). - New type re-exports:
TokenHoldersResponse,TokenLiquidityPoolsResponse.
tokens/opensea-token-holders.sh <chain> <address> [limit] [cursor] [sort_by] [sort_direction]tokens/opensea-token-liquidity-pools.sh <chain> <address> [limit]- Documentation: added rows to
SKILL.md(Investigation Scripts) andreferences/rest-api.md(Tokens).
Bumps consume
@opensea/api-types0.4.3 (released alongside, see the spec-sync PR for full schema details).
- Updated dependencies [96928f4]
- Updated dependencies [90702a7]
- @opensea/api-types@0.4.3
-
e7deba3: Rebuild the SDK's type layer on
@opensea/api-typeswith automatic case translation at the fetcher boundary. Consumer API stays camelCase; underneath, the fetcher snakeizes outgoing query params and POST bodies and camelizes responses, so the SDK no longer ships hand-rolled response shapes.The Order family, NFT/Trait, Drop family, Collection, Account, Payment, Chain, Token, and event response shapes now derive directly from the generated OpenAPI types via a generic
Camelize<T>mapper. When the API spec gains a field, the SDK type picks it up automatically — no per-endpoint converter to keep in sync. The oldutils/converters.tsis gone.utils/case.tsships two utilities:camelizeKeysDeep<T>/Camelize<T>— walks the API response and rewrites snake_case keys to camelCase.snakeizeKeysDeep<T>/Snakeize<T>— the inverse, applied to query params and POST bodies on the way out.
Consumers always see camelCase; the API always sees snake_case. No converter drift, no field-name typos.
Where the OpenAPI spec is too loose, the SDK still narrows:
Listing.typeis theOrderTypeenum (spec ships plainstring).Listing.status/Offer.statusare theOrderStatusenum.Order/Offer/Listing.protocolDatais the seaport-jsOrderWithCounter(the SDK passes it directly to Seaport).
These come from aligning with what the API actually returns:
Order.protocolDataandOrder.protocolAddressare optional. They're populated on every endpoint except the profile listings/offers endpoints, where the API intentionally returns null for performance. Code that reads them unconditionally needs a guard.Orderbase type no longer carriesprice— onlyOfferandListingdo (matching the API).OfferandListinggainremainingQuantity(required),orderCreatedAt, andasset?: OrderAsset(the field added in ProjectOpenSea/os2-core#42022 for profile endpoints).NFTis nowNftDetailed— gainsdisplayImageUrl,displayAnimationUrl,originalImageUrl,originalAnimationUrl,animationUrl,isSuspicious,subscription,owner.quantityString. Drops stalerarity.{score,calculatedAt,maxRank,tokensScored,rankingFeatures}that weren't actually in the spec.TokenBalancegains optionalstatus,baseTokenLiquidityUsd,quoteTokenLiquidityUsd.RarityStrategyis nowCamelize<Rarity>from api-types —{ strategyId, strategyVersion, rank? }. The previous extra fields (calculatedAt,maxRank,tokensScored) were spec-incomplete patches.GetCollectionResponseis now an alias forOpenSeaCollection— the previous{ collection: OpenSeaCollection }wrapper never matched the actual API response.- Acronym casing follows generic snake→camel rules:
is_nsfw→isNsfw(notisNSFW). PaymentToken.image(wasimageUrl) — the spec usesimage; the previous converter renamed it. Code readingpaymentToken.imageUrlshould switch topaymentToken.image.
utils/converters.ts(collectionFromJSON,accountFromJSON,paymentTokenFromJSON,feeFromJSON,rarityFromJSON,pricingCurrenciesFromJSON) and the corresponding test file.
Profile endpoints (
/account/{address}/listings,/offers,/offers_received) now exposeasset: { identifier?: string; contract: string }, so consumers no longer have to parse SeaportprotocolData.parameters.offer[0]to identify the NFT.
-
fb03c09: Source
EventPayment,EventAsset,GetNFTResponse,BuildOfferResponse, andCancelOrderResponsefrom@opensea/api-typesinstead of hand-rolling them. Same shapes consumers see today (after camelize at the fetcher), now auto-tracking the OpenAPI spec.EventPayment→Camelize<Payment>EventAsset→Camelize<Nft>(gainsoriginal_image_url,original_animation_url, andtraitsfields the API also returns)GetNFTResponse→Camelize<NftResponse>BuildOfferResponse→Camelize<BuildOfferResponse>(api-types ships this with camelCase keys natively)CancelOrderResponse→Camelize<CancelResponse>
The narrow event types (
ListingEvent,OfferEvent,TraitOfferEvent,CollectionOfferEvent,OrderEvent,MintEvent,SaleEvent,TransferEvent) andAssetEventunion keep their existing SDK definitions — they're refinements that narroweventTypeto specific enum values, which the api-typesOrderEvent/SaleEvent/TransferEventschemas don't model. -
68b07cb: Fix critical bugs introduced by the api-types migration where unconditional body snakeize corrupted Seaport-shaped POST payloads.
The OpenSea OpenAPI spec is mixed-casing: outer envelope keys are snake_case (
protocol_address,protocol_data,order_hash) but inner Seaport struct keys are camelCase to mirror the on-chain struct (parameters.startTime,parameters.endTime,parameters.orderType,parameters.zoneHash,parameters.conduitKey,parameters.totalOriginalConsiderationItems,parameters.offer[].itemType,parameters.offer[].identifierOrCriteria, etc.). A few top-level request fields are also camelCase per spec:CancelRequest.offererSignature,CriteriaObject.numericTraits.The blanket
snakeizeKeysDeep(body)at the fetcher boundary recursively rewrote every inner key to snake_case, breaking:postListing/postOffer— Seaportparameterssent with snake_case keys the API rejected (or that no longer matched the EIP-712 signature digest).offchainCancelOrder—offererSignatureshipped asofferer_signature, silently dropping the cancel signature.buildOffer/postCollectionOffer—criteria.numericTraitsshipped asnumeric_traits, broadening trait offers to the whole collection.
Added
snakeizeBody?: boolean(defaulttrue) to the publicFetcher.post()method. Internal callsites whose wire bodies contain camelCase keys now passsnakeizeBody: falseand emit bodies in exact wire shape:OrdersAPI.postListing,OrdersAPI.postOffer— outerprotocol_addresssnake_case; innerparameterspreserved camelCase via spread of the SeaportOrderWithCounter.OrdersAPI.offchainCancelOrder— body{ offererSignature }preserved.OffersAPI.buildOffer,OffersAPI.postCollectionOffer— outerprotocol_address/protocol_data/offer_protection_enabledsnake_case;criteria.numericTraitspreserved camelCase.
The default behavior (snakeize-all) is unchanged for any caller of
api.post()that doesn't hit a mixed-casing endpoint.OpenSeaAPI.requestInstantApiKey(and theOpenSeaSDKpassthrough) now camelizes its response — previously it calledfetch()directly and returned snake_case despite the typed surface promising{ apiKey, expiresAt, ... }. JSDoc examples on both methods corrected.OpenSeaRateLimitError.responseBodyis now camelized to match the rest of the boundary contract._fetcherror envelope is camelized before reading.errors, so nested snake_case keys no longer leak into thrown Error messages.camelToSnakeno longer emits a leading underscore for PascalCase / acronym keys (URL→url,MyKey→my_key). The correspondingSnakeize<T>type was updated to match the runtime.OpenSeaAccount.socialMediaAccountsdefends against the wire returningnull(the previous hand-rolled converter did?? []; the new pipeline did not).- Dead-code OrderV2/Order casts dropped in
fulfillment.ts— both branches read the same camelCase property after the migration.
Added 11 unit tests covering
snakeizeKeysDeep(flat + nested objects, array walking, multi-segment, primitives, null/undefined, Date passthrough, top-leveloffererSignature/protocolAddressrewrite, position-0 guard). The previous test file imported onlycamelizeKeysDeep— the entire outbound translator had zero unit coverage, which is how these bugs slipped through.A new CI workflow (
.github/workflows/sdk-integration.yml) runs the SDK integration suite nightly and on PRs labeledrun-integration, so future fetcher-boundary regressions are caught against the live API. -
Updated dependencies [fb03c09]
- @opensea/api-types@0.4.2
-
051b558: Surface 22 new endpoints added in
@opensea/api-types0.4.0 as SDK methods and CLI commands.@opensea/sdk— new methods onOpenSeaAPI(and the underlying domain clients):getTokensBatch,getNFTsBatch,getCollectionsBatch— batch lookupscreateListingActions— ordered approval + Seaport-sign actions for new listingsdeployDropContract,getDeployContractReceipt— drop contract deploymenttransferAssets— build transactions to transfer NFTs or tokensgetCollectionOfferAggregates,getCollectionHolders,getCollectionFloorPrices— collection analyticsgetTokenPriceHistory,getTokenOhlcv,getTokenActivity— token analyticsgetNFTOwners,getNFTAnalytics— NFT analyticsgetPortfolioStats,getPortfolioHistory,getProfileOffers,getProfileOffersReceived,getProfileListings,getProfileFavorites,getProfileCollections— account profile
New internal
AssetsAPIclient; new request/response types re-exported through@opensea/sdk(from@opensea/api-types).@opensea/cli— new commands on the existingaccounts,collections,nfts,tokens,listings,dropssubcommands, plus a newassets transfersubcommand. SDK class methods mirroring the same surface added toOpenSeaCLI.No removed endpoints; pure additive release.
-
94dbf08: Sync downstream packages to the API surface introduced in
@opensea/api-types0.3.0 (os2-core#40171 + #40190): drop methods backed by removed endpoints, fix POST shapes, and surface the four new endpoints (/listings/sweep,/offers/collection/{slug}/nfts/{identifier},/swap/execute,/transactions/receipt).Removed methods (the underlying GET endpoints were deleted; they would return 404 against the new API):
OpenSeaAPI.getOrder/OrdersAPI.getOrder— was already@deprecated. UsegetBestOffer/getBestListingfor "best" orgetAllOffers/getAllListingsfor collection-wide results.OpenSeaAPI.getOrders/OrdersAPI.getOrders— was already@deprecated. UsegetAllOffers/getAllListings.OpenSeaAPI.postOrder/OrdersAPI.postOrder— was already@deprecated. UsepostListing/postOffer.OpenSeaAPI.getNFTOffers/OffersAPI.getNFTOffers— replaced bygetOffersByNFT(slug, tokenId)(new endpoint takes a collection slug, not contract address).OpenSeaAPI.getNFTListings/ListingsAPI.getNFTListings— no per-NFT all-listings endpoint exists. UsegetBestListing(slug, tokenId)for the best, orgetAllListings(slug)and filter client-side.- Helpers
getOrdersAPIPath,serializeOrdersQueryOptions,deserializeOrder— orphaned with the methods above. - Types
OrderAPIOptions,OrdersQueryOptions,OrdersQueryResponse,OrdersPostQueryResponse,ListingPostQueryResponse,OfferPostQueryResponse,SerializedOrderV2,GetOrdersResponse— unused after the deletions. - Stats fields
IntervalStat.{volume_diff, volume_change, sales_diff, average_price}andStats.{market_cap, average_price}— server stopped returning them (always0previously).
Behavior changes:
OrdersAPI.postListingandOrdersAPI.postOffernow read the bareListing/Offerresponse (the upstream API dropped the legacyorderwrapper field).OpenSeaSDK.createOfferreturnsPromise<Offer>(wasPromise<OrderV2>).OpenSeaSDK.createListingreturnsPromise<Listing>(wasPromise<OrderV2>).OpenSeaSDK.createBulkListingsreturnsPromise<BulkOrderResult<Listing>>;createBulkOffersreturnsPromise<BulkOrderResult<Offer>>.BulkOrderResultis now generic in the success type.
New methods:
OpenSeaAPI.getOffersByNFT(slug, identifier, limit?, next?)— all offers for one NFT.OpenSeaAPI.sweepCollection(request)— bulk-buy items from a collection, any payment token (incl. cross-chain).OpenSeaAPI.executeSwap(request)— multi-asset swap; companion togetSwapQuote.OpenSeaAPI.getTransactionReceipt(request)— fetch transaction status (sweep, swap, fulfillment).- New
TransactionsAPIsub-client.
OrdersResponse,SimpleAccountre-exports removed fromsrc/types/api.ts(schemas no longer exist).offers allandlistings allnow accept--maker <address>to filter by order maker.- New commands:
listings sweep— bulk-buy items from a collection with any payment token.offers by-nft <collection> <token-id>— all offers for a specific NFT.transactions receipt --request <file>— fetch transaction receipt/status (request body via JSON file).
- New SDK helpers:
OpenSeaCLI.transactions.receipt,SwapsAPI.executeMulti(POST/swap/execute).
opensea-api/references/rest-api.md— endpoint tables refreshed: removed deleted GET rows, added?maker=annotations, addedlistings/sweep, per-NFT offers,swap/execute, andtransactions/receiptrows.opensea-marketplace/references/marketplace-api.md— replaced "Get listings/offers for specific NFT" sections (which curled the removed endpoints) with the slug-based replacements.
- Updated dependencies [7a51fd0]
- @opensea/api-types@0.3.0
-
961f2c5: fix(api): consume cross-chain fulfillment types from
@opensea/api-typesThe cross-chain fulfillment types added in the previous release were hand-rolled in
packages/sdk/src/api/types.tsandpackages/cli/src/types/api.tsrather than generated from the OpenAPI spec. This release pulls them from@opensea/api-types(the source of truth) so future spec changes flow through automatically.@opensea/api-types: Adds named exports forCrossChainFulfillmentRequest,CrossChainFulfillmentResponse,CrossChainPaymentToken,FulfillerObject, andListingObjectschemas (regenerated from the production OpenAPI spec).@opensea/sdk(type rename — minimal-impact since the prior release shipped <1 day ago):CrossChainListing→ListingObjectCrossChainFulfillmentDataRequest→CrossChainFulfillmentRequestCrossChainFulfillmentDataResponse→CrossChainFulfillmentResponseCrossChainTransaction→SwapTransactionResponse
The runtime call signature on
BaseOpenSeaSDK.getCrossChainFulfillmentData()is unchanged.@opensea/cli(type rename — same minimal impact):CrossChainFulfillmentTransaction→SwapTransactionResponseCrossChainFulfillmentDataResponse→CrossChainFulfillmentResponse
Adds a new blocking CI check (
pnpm check-api-paths) that fails when an/api/v2/...URL referenced in SDK or CLI source is not present inpackages/api-types/opensea-api.json. AGENTS docs updated to make the api-types-first flow explicit for new endpoints. -
Updated dependencies [961f2c5]
- @opensea/api-types@0.2.3
-
fc44d9f: feat: add cross-chain fulfillment support
Add support for the new
POST /api/v2/listings/cross_chain_fulfillment_dataendpoint across SDK, CLI, and skill packages.SDK: New
getCrossChainFulfillmentData()method on both the API client and the base SDK class. Accepts listings, fulfiller, payment token (chain + address), and optional recipient. Returns ordered transactions to sign and submit.CLI: New
listings cross-chain-fulfillsubcommand with--hashes,--listing-chain,--protocol-address,--fulfiller,--payment-chain,--payment-token, and optional--recipientflags. Supports sweeping multiple listings via comma-separated hashes.Skill: New
opensea-cross-chain-fulfill.shscript and updated SKILL.md with cross-chain buying workflow documentation.
- 4a76bc1: Add server-side trait filtering on three collection-scoped read methods.
getNFTsByCollection,getBestListings, andgetEventsByCollectionnow accept an optionaltraitsargument (aTraitFilter[]); multiple entries are AND-combined server-side. The SDK JSON-encodes the array for the request — callers pass a structured[{ traitType, value }]. New exports:TraitFilter,GetEventsByCollectionArgs,encodeTraitsParam. Requires@opensea/api-types@^0.2.2.
-
bc9c6ce: Add token-groups and instant API key endpoints.
SDK:
sdk.api.getTokenGroups({ limit?, cursor? })andsdk.api.getTokenGroup(slug)for the new/api/v2/token-groupsendpoints.OpenSeaSDK.requestInstantApiKey()andOpenSeaAPI.requestInstantApiKey()— static methods that callPOST /api/v2/auth/keyswithout authentication and return a free-tier key you can pass into the SDK constructor. Rate limited to 3 keys/hour per IP; keys expire after 30 days.OpenSeaAPIclass is now exported from the package root (@opensea/sdkand@opensea/sdk/viem).
CLI:
- New
opensea token-groups listandopensea token-groups get <slug>commands. - New
opensea auth request-keycommand — works without--api-key/OPENSEA_API_KEYsince the endpoint is unauthenticated.
- a57c63d: Update @opensea/seaport-js from ^4.0.7 to ^4.1.1
- Updated dependencies [5b6ba13]
- @opensea/api-types@0.2.1
- 497b636: Add missing API wrapper methods for full OpenAPI spec coverage:
getNFTCollection()— get the collection an NFT belongs togetNFTMetadata()— get raw NFT metadata (name, description, image, traits)- Expose
fulfillPrivateOrder()as a public method onOpenSeaSDK
-
bc5b7b6: Add viem support via provider abstraction layer.
Breaking changes:
OrderSide.LISTINGvalue changed from"ask"to"listing"OrderSide.OFFERvalue changed from"bid"to"offer"BigNumberishtype replaced withAmount(string | number | bigint)Overridestype replaced withRecord<string, unknown>providerpublic property removed fromOpenSeaSDKclassestimateGasutility function removed- TypeChain dependency removed (replaced with inline ABIs)
ethers.FetchRequestreplaced with nativefetch()
New features:
@opensea/sdk/viemsubpath export with native viemPublicClient/WalletClientsupport- Provider abstraction types:
OpenSeaSigner,OpenSeaProvider,ContractCaller,OpenSeaWallet ZERO_ADDRESSandMAX_UINT256exported from constantschecksumAddressutility using@noble/hashesparseUnitsandparseEtherstandalone utilities
-
Rename package from
opensea-jsto@opensea/sdkThe old
opensea-jspackage has been deprecated with a stub that directs users to install@opensea/sdkinstead.
-
b3a5e84: Add drops endpoints, trending/top collections, and account resolve
- api-types: Sync OpenAPI spec with 6 new endpoints and 8 new schemas (drops, trending/top collections, account resolve)
- SDK: New DropsAPI class, extended CollectionsAPI and AccountsAPI with new methods
- CLI: New
dropscommand,collections trending/topsubcommands,accounts resolvesubcommand
-
f82c035: Replace hardcoded chain ID maps with codegen from OpenSea REST API
- SDK: Fix Blast chain ID from 238 (testnet) to 81457 (mainnet)
- CLI: Add chains previously only in SDK (b3, flow, ronin, etc.)
- CLI: Remove
bsc,sepolia,base_sepolia,monad_testnetfromCHAIN_IDS— these are not in the OpenSea API - Add
pnpm sync-chainscodegen script (fetches GET /api/v2/chains as source of truth)
-
Updated dependencies [b3a5e84]
- @opensea/api-types@0.2.0