English
English
Appearance
English
English
Appearance
The default POST /pin flow works by hunting the public DHT for peers that advertise your CID. That fails for content living on a peer that:
Reprovider.Enabled = false)For those cases, tell our cluster exactly where the content lives by passing one or more multiaddresses on the pin request. We swarm connect to each before the pin runs, so the DAG fetch talks directly to your peer instead of wandering the DHT.
On the machine that hosts the CID, run:
ipfs idYou'll see something like:
{
"ID": "12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3",
"Addresses": [
"/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3",
"/ip4/203.0.113.42/tcp/4001/p2p/12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3",
"/ip4/203.0.113.42/udp/4001/quic-v1/p2p/12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3"
],
...
}Pick the addresses our cluster can actually reach from the internet:
/ip4/<your-public-ip>/tcp/4001/p2p/<PeerID> and /ip4/<your-public-ip>/udp/4001/quic-v1/p2p/<PeerID>/ip4/127.0.0.1/... and RFC1918 addresses (10.*, 192.168.*) — those are your local network; they'll fail from our side/dnsaddr/your.domain.com/tcp/4001/p2p/<PeerID> if you've published a _dnsaddr TXT recordBehind NAT?
If your machine is behind NAT, enable Kubo's AutoRelay + hole-punching (Swarm.RelayClient.Enabled = true, Swarm.EnableHolePunching = true) so we can reach it through a relay. Or run your Kubo on a small public VPS and swarm-connect there.
Once you have a public multiaddress, add it to the pin request:
curl -X POST https://api.ipfs.ninja/pin \
-H "X-Api-Key: bws_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"cid": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"description": "staging build v42",
"multiaddresses": [
"/ip4/203.0.113.42/tcp/4001/p2p/12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3"
]
}'The response includes a swarmConnected array with per-hint status:
{
"cid": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"status": "pinning",
"swarmConnected": [
{
"multiaddr": "/ip4/203.0.113.42/tcp/4001/p2p/12D3KooWH3uV…",
"ok": true,
"strings": ["connect 12D3KooWH3uV… success"]
}
],
"uris": { "url": "https://ipfs.ninja/ipfs/bafybeigdyrzt5…" }
}Up to 5 multiaddresses per pin. If your node has several routable addresses (IPv4 + IPv6, TCP + QUIC), list them all — the first one that connects wins the block fetch:
{
"cid": "bafybeigdyrzt5...",
"multiaddresses": [
"/ip4/203.0.113.42/tcp/4001/p2p/12D3KooWH3uV…",
"/ip4/203.0.113.42/udp/4001/quic-v1/p2p/12D3KooWH3uV…",
"/ip6/2001:db8::1/tcp/4001/p2p/12D3KooWH3uV…",
"/dnsaddr/node.myapp.com/tcp/4001/p2p/12D3KooWH3uV…"
]
}ok: true — the cluster peered with your node successfully. The pin's DAG fetch will attempt this peer first before falling back to the DHT.ok: false with error: "dial to peer: no route" — network unreachable. Check that the multiaddress uses a public IP and the port isn't firewalled.ok: false with error: "timeout of 5000ms exceeded" — the peer didn't respond in 5 seconds. Slow relay or offline node.ok: false with error: "peer id mismatch" — the peer at that address advertises a different PeerID than the one in your multiaddress. Re-check the multiaddress.A failing connect does not fail the pin — the pin proceeds with the DHT path. swarmConnected is diagnostic, not fatal.
The most common shapes are supported:
| Transport | Example |
|---|---|
| IPv4 TCP | /ip4/203.0.113.42/tcp/4001/p2p/QmPeerId |
| IPv6 TCP | /ip6/2001:db8::1/tcp/4001/p2p/QmPeerId |
| IPv4 QUIC v1 | /ip4/203.0.113.42/udp/4001/quic-v1/p2p/QmPeerId |
| DNS + WSS | /dns4/node.example.com/tcp/443/wss/p2p/QmPeerId |
| dnsaddr | /dnsaddr/node.example.com/tcp/4001/p2p/QmPeerId |
Must end in /p2p/<PeerID> (either legacy base58btc Qm…/12D… or CIDv1-encoded bafz…/k51…). If a legitimate multiaddress shape gets rejected, open a support ticket with the exact multiaddress and we'll widen the validator.
POST /pin — full parameter list and response shape