
A CID (content identifier) is the address IPFS builds from a hash of your content's root block. It also records how that hash was made and how to read the data, so any node can check what it fetched. Below, we take one real CID apart byte by byte.
TL;DR:
Qm, always base58btc, dag-pb and sha2-256, and it is only the multihash0x01 for the version, 0x70 for dag-pb) and keeps the same digest; Kubo does it with ipfs cid format -v 1 -b base32cid field from every pin call, and you can pin an existing CID with pinByHashUpdated Oct 19, 2026: added our own byte decode, the docs' ipfs cid format examples, multibase and v0 to v1 sections, a diagram, and Kubo's real default.
The IPFS docs define a content identifier as a label that points to material in IPFS without saying where it is stored. It is a content address: the identifier comes from the content itself, so any difference in the content produces a different CID.
That gives you a check that a location address can't. When you fetch /ipfs/<CID> from any peer or gateway, you can hash what came back and compare. The same content added with the same settings on two nodes produces the same CID, which is why many unrelated nodes can serve one file.
A CID stays short no matter how large the content is, and the 2.59 GiB Ubuntu image in the IPFS docs example still gets a 46-character CIDv0.
A CIDv1 string decodes into four fields, and each one answers a question a reader of the data would otherwise have to guess:
b means base32, the default for CIDv1, and the prefix only exists in the text form, not in the binary CID.0x01 for CIDv1.dag-pb (0x70, used by UnixFS files and folders), raw (0x55, plain bytes), dag-cbor (0x71) and dag-json (0x0129).0x12 for sha2-256), the digest length (0x20, which is 32 bytes), then the digest itself.
We decoded the IPFS docs' example CID, bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi, with a few lines of Python and a plain base32 decoder, so you don't need an IPFS node for this. Dropping the b and decoding the rest gives 36 bytes:
b multibase prefix: base32 (text form only)
01 CID version 1
70 multicodec: dag-pb
12 multihash function: sha2-256
20 digest length: 32 bytes
c3c4733ec8affd06cf9e9ff50ffc6bcd2ec85a6170004bb709669c31de94391a
the sha2-256 digest of the root blockNotice that every CIDv1 for dag-pb and sha2-256 starts with the same four bytes. That is why so many CIDs you see begin with bafybei while raw-codec CIDs begin with bafkrei, and the prefix tells you the format before you fetch anything.
Kubo can print these fields for you with ipfs cid format. Its help text lists format codes such as %c for the codec name, %h for the multihash name and %P for the whole prefix as version, codec, hash and length. For a readable breakdown, the same help points you to ipfs cid inspect.
CIDv0 was the first design, a base58btc-encoded multihash and nothing else, and if a CID is 46 characters and starts with Qm, the IPFS docs say it is a CIDv0. Its codec is always dag-pb and its hash is always sha2-256, because the string has no room to say otherwise.
Our decode shows how close the two versions are. The CIDv0 of the same content, QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR, decodes to 34 bytes, and those bytes match the CIDv1 exactly once you drop its 01 70 header.
The version you get by default depends on the tool. Kubo's config docs list Import.CidVersion with a default of 0, so a plain ipfs add still returns a Qm CID. The IPFS docs recommend CIDv1 for new projects with ipfs add --cid-version 1, and Kubo's unixfs-v1-2025 import profile uses CIDv1.
The IPFS docs show the conversion with Kubo's built-in command. We don't have an IPFS binary on this machine, so these are the docs' own examples, not output we ran:
$ ipfs cid format -v 1 -b base32 QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR
bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
$ ipfs cid format -v 0 bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnROur Python decode reproduces the same pair in both directions, which is a useful check when you can't install Kubo. If you work in JavaScript, you get the same result from toV1() and toV0() in the multiformats library.
The trip back to v0 only works for dag-pb, since the docs say a CIDv1 with the raw, dag-cbor or dag-json codec can't become a CIDv0. If you only need to normalize CIDs from other sources, ipfs cid base32 converts them to base32 CIDv1.
A CIDv1 can be written in any multibase encoding, and the first character tells you which. The prefix b is base32, z is base58btc, k is base36 and f is base16 (hex), but the bytes underneath don't change, so these strings all name the same content.
Base32 is the default because it is case-insensitive. A subdomain gateway puts the CID in a DNS label, and DNS ignores case, so a base58 CID would break there. The IPFS docs note that subdomain gateways redirect other bases to base32 or base36, and they suggest base36 for IPNS names.
Usually not, and the IPFS docs show why with an Ubuntu ISO. The SHA-256 checksum Ubuntu publishes starts b45165ed, while the digest inside the file's CID starts 0E7071C5, and running shasum --check with it fails.
The CID hashes the root block of the file's DAG, not the file's bytes. IPFS splits a large file into chunks, links them into a tree and wraps them in a codec, so the root block holds links rather than your data. The one exception the docs name is a single-block file stored with the raw codec, where the digest is a plain hash of the file.
Every pinning response in the AIOZ Pin API includes a cid field, and you read the file back at https://public.aiozpin.network/ipfs/{cid}. Because the CID is standard, you can decode it with any multiformats tool and check it against a CID you computed yourself.
If you already have a CID, you don't need to upload the file again. The pinning docs pin it by CID with hash_to_pin, and the CLI on the SDKs page does the same:
pinning pin --hash QmdYTBNig2d4dQd5o1LXM3NHbCYA7168NpN5R9m44vDj88 --keyvalue key1:value1What the docs don't cover yet: which CID version and import settings the service uses for uploaded files. Every example CID in our docs is a CIDv0 starting with Qm. For the request and response fields, see the AIOZ Pin Pinning API page.
What does CID stand for? Content identifier, the self-describing hash-based address IPFS uses for every block of content.
Why do some CIDs start with Qm and others with bafy? Qm marks a CIDv0 in base58btc, while bafy marks a base32 CIDv1 for dag-pb and sha2-256, because those first bytes are the same for every such CID.
Can every CIDv1 be converted to CIDv0? No. Only dag-pb CIDs can go back to v0, while raw, dag-cbor and dag-json CIDs return an error.
Does the same file always get the same CID? Only with the same settings, because chunk size, DAG layout, codec, CID version and hash function all change the result.
Can two different files share a CID? Only through a hash collision, and with sha2-256 finding one is computationally infeasible.
Does AIOZ Pin use a custom CID format? No. The API returns standard IPFS CIDs that any CID library can decode, and the gateway serves them at the usual /ipfs/{cid} path.

ERC-1155 metadata on IPFS breaks when filenames ignore the {id} rule. Here is the exact 64-character format, a working folder layout, and the per-token option.

AIOZ Pin rate limits in one place: 180 requests per minute for the API, 15 per CID on the public gateway, and no predefined limit on premium gateways.

IPFS pin stuck on Pinning? Here is what Pinning, Pinned, and Failed mean on AIOZ Pin, why big directories can sit there, and how to read a pin's real state.

Two identical files, three IPFS tools, three different CIDs. Here is why that happened for years, and how IPIP-0499 made content addressing deterministic.

AIOZ Pin MCP server setup has two paths: llms.txt lets a super intelligence assistant read the API, the MCP server lets it call 11 tools. Here is each one.

AIOZ Pin bills three flat rates against a token wallet, with no tiers to pick between. Here is what storage, bandwidth and pinned files cost, with examples.