
The AIOZ Pin NFT API is what the Node.js SDK's pinNft() actually calls under the hood, three raw REST endpoints, useful to know directly if you're automating from a language other than JavaScript, or building a pipeline where pulling in the SDK is more overhead than a few direct HTTP calls. This covers the actual endpoints, what they return, and a detail the SDK abstracts away: an "NFT" on AIOZ Pin is really two coordinated pins tracked under one record, not a single blob.
TL;DR:
POST /api/nft/ creates an NFT record, pinning the uploaded file as the asset and its metadata as a separate, linked pinGET /api/nft/:nftId retrieves one NFT record by IDGET /api/nft/nfts/ lists your NFTs with pagination, filtering by pinned status, and sortingpinning_api_key/pinning_secret_key headers, not a Bearer tokenPOST https://api.aiozpin.network/api/nft/?cid=<optional-existing-asset-cid>
Headers: pinning_api_key, pinning_secret_key
Body: file (read stream), metadata (stringified JSON, optional)
A successful call returns 201 Created with an object containing id, asset_cid, metadata_cid, asset_pin_id, metadata_pin_id, size, user_id, created_at, updated_at, pinned, status, and a metadata_asset object with name and type. Notice there are two separate CIDs and two separate pin IDs in that response, asset_cid/asset_pin_id for the file itself, metadata_cid/metadata_pin_id for the metadata. That's the actual mechanism behind "pin an NFT's asset and metadata together": it's two pins created and tracked as one coordinated NFT record, not one file containing both. Worth knowing if you're building anything that inspects pin status directly, since a failure could in principle affect one half without the other.
GET https://api.aiozpin.network/api/nft/:nftId
Headers: pinning_api_key, pinning_secret_key
Returns the same object shape as the create call. Useful for polling status after creation, or looking up an NFT record you created previously by its id rather than by CID.
GET https://api.aiozpin.network/api/nft/nfts/?offset=0&limit=10&pinned=all&sortBy=created_at&sortOrder=DESC
Headers: pinning_api_key, pinning_secret_key
Supports offset/limit for pagination, pinned (all, true, or false) to filter by pin status, and sortBy (created_at, size, or name) with sortOrder (ASC/DESC). The response includes a totals object (files, size) alongside the nfts array, useful for dashboards or scripts that need aggregate numbers without pulling every record and summing manually.
The request shape above translates directly into a real call, useful for testing the endpoint before wiring it into an actual pipeline:
curl -X POST "https://api.aiozpin.network/api/nft/" \
-H "pinning_api_key: your_key" \
-H "pinning_secret_key: your_secret" \
-F "[email protected]" \
-F 'metadata={"name":"Artwork #001","description":"Generative piece"}'
A successful response returns the full object described above, including both CIDs. Worth testing this against a small file first, since a malformed metadata JSON string fails the whole call rather than pinning the asset with metadata silently dropped, better to catch that from a curl response body directly than from a pipeline log three steps removed from the actual request.
status Field TracksThe status field on an NFT record reflects where the underlying pins are in their lifecycle, not just a flat true/false. A newly created record typically starts in a processing state before settling into a resolved one once both the asset and metadata pins are confirmed, the same pinned/queued/failed distinction this blog's coverage of the IPFS Pinning Service API standard describes for pin status generally, since AIOZ Pin's Nft API is built on the same underlying pinning infrastructure. Polling GET /api/nft/:nftId and checking status (rather than assuming the create call's 201 Created response means both pins already fully resolved) is the reliable way to know an NFT record is actually ready to reference on-chain, not just accepted for processing.
Unlike the Users and ApiKeys endpoints, which use Authorization: Bearer <access_token>, all three Nft API endpoints authenticate with pinning_api_key and pinning_secret_key as separate headers, the raw scoped key and secret rather than a bearer token. If you're automating this from a script that also calls account-management endpoints, don't assume one auth pattern works everywhere, check which header format the specific endpoint you're calling expects.
Automating this at any real volume, minting a few thousand NFTs in a batch job, means planning for a call to fail partway through rather than assuming every request in a loop succeeds. Because the create endpoint pins the asset and metadata as two separate tracked pins under one record, a failure can in principle leave one half pinned and the other not, worth checking GET /api/nft/:nftId after any batch run rather than treating a 201 Created response as proof both pins fully resolved before you move on. A defensive batch script retries a failed create call with the same file (idempotent in the sense that pinning the same content twice produces the same CID rather than a duplicate), and logs the nftId of anything that doesn't reach a resolved status after a reasonable number of polling attempts, so a handful of stragglers in a run of thousands don't silently slip through unnoticed.
The SDK is the better default for a Node.js project, it's fewer lines and handles the request formatting for you. Direct calls to the Nft API make more sense in a few specific cases: automating from Python, Go, or another language without an official AIOZ Pin SDK, building a CLI-style webhook-triggered pipeline where adding a Node.js dependency is disproportionate to the task, or needing the raw response fields (like separate asset_pin_id/metadata_pin_id) that a higher-level wrapper might not surface directly.
What does the AIOZ Pin NFT API's create endpoint actually do? POST /api/nft/ pins an uploaded file as the asset and its metadata as a second, linked pin, returning one NFT record that tracks both.
Does creating an NFT produce one CID or two? Two. The response includes a separate asset_cid for the file and metadata_cid for the metadata, each with its own pin ID, tracked together under one NFT record.
What authentication does the Nft API use? pinning_api_key and pinning_secret_key headers, not the Authorization: Bearer token used by account and key-management endpoints.
Can I filter or sort my NFT list through the API? Yes. GET /api/nft/nfts/ supports pagination (offset/limit), filtering by pin status (pinned), and sorting by created_at, size, or name.
Do I need the Node.js SDK to pin NFTs on AIOZ Pin? No. The SDK's pinNft() wraps these same REST endpoints, useful direct if you're automating from another language or want the raw response fields.
pinNft() wrapper this API sits underneath
IPFS defaults to 256 KiB fixed-size chunks, but also ships Rabin and Buzhash content-defined chunkers. Here is why the choice affects deduplication.

An IPFS CID is not a random string. It encodes a version, a codec, and a hash algorithm plus digest. Here is how to decode a real CID piece by piece.

IPFS does not use a B-tree for large directories. It uses a HAMT, a Hash Array Mapped Trie. Here is exactly how it shards a folder once it outgrows one block.

AIOZ Pin image resizing happens straight in the gateway URL, no upload step or separate service. Here is every img- parameter, with real srcset examples.

x402 payments let ERC-8004 weight a paid AI agent interaction more heavily than free work in its reputation score. Here is exactly how that link works.

AIOZ Pin NFT API calls pin an asset and its metadata as two tracked pins under one record. Here is how to automate it directly over REST, no SDK needed.