Developer quick start
This is the shortest path from zero to a successful API call. For the full end-to-end (create, upload, deploy, mint) walk-through, see mint an NFT end-to-end.
Install the SDK
Section titled “Install the SDK”bun add @highlightxyz/sdkThe SDK is an ESM-only TypeScript package. Works on Bun, Node 20+, and modern browsers.
Try a public call first
Section titled “Try a public call first”A small set of endpoints work without auth. Use one to verify your setup:
import { createHighlightClient } from "@highlightxyz/sdk";
const client = createHighlightClient({ baseUrl: "https://api.highlightv2.xyz",});
const chains = (await client.config.chains()).data!;console.log(chains.map((c) => `${c.name} (${c.chainId})`));If you see a list of chains, you’re wired up.
Authenticate
Section titled “Authenticate”For anything write-related, you need a JWT. SIWE is the canonical path:
import { createSiweMessage } from "viem/siwe";import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const { nonce } = (await client.user.siwe.nonce()).data!;
const message = createSiweMessage({ address: account.address, chainId: 1, domain: new URL("https://api.highlightv2.xyz").host, nonce, uri: "https://api.highlightv2.xyz", version: "1", issuedAt: new Date(), expirationTime: new Date(Date.now() + 10 * 60 * 1000),});
const signature = await account.signMessage({ message });
const { tokens } = (await client.user.signin({ body: { providerType: "Siwe", message, signature },})).data!;
const authed = createHighlightClient({ baseUrl: "https://api.highlightv2.xyz", auth: () => tokens.accessToken, security: [{ type: "http", scheme: "bearer" }],});Access tokens last 15 minutes. See reference/auth for refresh patterns, Privy sign-in, and API keys.
Your first authenticated call
Section titled “Your first authenticated call”const mine = (await authed.collection.list({ blockchains: [84532], // Base Sepolia testnet: true, types: ["OpenEdition", "LimitedEdition", "OneOfOne", "Series", "GenerativeSeries"], limit: 20,})).data!;
console.log(`${mine.pagination.total} collections`);blockchains, testnet, and types are required — this is by design; unbounded listing is never what you want.
Response shape
Section titled “Response shape”Every method returns { data, error, response }. No exceptions on non-2xx:
const res = await authed.collection.get({ highlightId: "does-not-exist" });if (res.error) { console.log(`${res.response?.status}: ${JSON.stringify(res.error)}`); // e.g. "404: { name: \"CollectionNotFoundError\", ... }"}See reference/errors for the full typed-error catalog.
Where to go next
Section titled “Where to go next”- Full pipeline — Mint an NFT end-to-end
- Deploy details — Deploy workflow
- Media — Media upload flow
- Access control — Gated sales
- Auction mechanics — Ranked auctions
- All SDK clients — Clients overview
- All REST routes — REST API