Warning: Pinion is in active development and the software is constantly in flux. This documentation is not guaranteed to be up to date and may not reflect the current state of the APIs.
The Pinning Service API allows you to manage and persist content on IPFS by "pinning" CID objects. Pinning ensures that specific data remains available and is not garbage-collected by IPFS nodes.
This API is compatible with the IPFS Pinning Service API specification v1.0.0.
All endpoints require authentication using a Bearer token.
Authorization: Bearer <API_TOKEN>
To create or manage API tokens, visit your Account Settings.
Retrieve a list of pinned or pinning requests.
| Name | Type | Description |
|---|---|---|
| cid | string | Filter by specific CID (exact match or comma-separated list) |
| name | string | Filter by user-defined pin name |
| status | string | Filter by pin status (queued, pinning, pinned, failed) |
| limit | integer | Maximum number of results to return |
| before | string | Return results created before this ISO 8601 timestamp |
| after | string | Return results created after this ISO 8601 timestamp |
{
"count": 1,
"results": [
{
"requestid": "a7b3f77e-...-4fae",
"status": "pinned",
"created": "2025-10-27T00:00:00Z",
"pin": {
"cid": "bafybeigdyrztp...",
"name": "my-photo",
"origins": ["/ip4/203.0.113.1/tcp/4001/p2p/QmExample"],
"meta": {"source": "user-upload"}
},
"delegates": ["/ip4/203.0.113.2/tcp/4001/p2p/QmDelegateNode"]
}
]
}Create a new pin request.
{
"cid": "bafybeigdyrztp...",
"name": "project-backup",
"origins": ["/ip4/203.0.113.10/tcp/4001/p2p/QmOrigin"],
"meta": {"environment": "production"}
}{
"requestid": "8f3e4dc1-...-9ef1",
"status": "queued",
"pin": {
"cid": "bafybeigdyrztp...",
"name": "project-backup",
"origins": ["/ip4/203.0.113.10/tcp/4001/p2p/QmOrigin"],
"meta": {"environment": "production"}
},
"delegates": [],
"created": "2025-10-27T00:00:00Z"
}Retrieve metadata and status for a specific pin request.
{
"requestid": "8f3e4dc1-...-9ef1",
"status": "pinned",
"pin": {
"cid": "bafybeigdyrztp...",
"name": "project-backup",
"origins": [],
"meta": {"environment": "production"}
},
"delegates": [
"/ip4/198.51.100.22/tcp/4001/p2p/QmDelegateNode"
],
"created": "2025-10-27T00:00:00Z"
}Replace the pin for a given request ID with a new CID or metadata.
{
"cid": "bafybeicx...",
"name": "project-backup-v2"
}{
"requestid": "8f3e4dc1-...-9ef1",
"status": "queued",
"pin": {
"cid": "bafybeicx...",
"name": "project-backup-v2"
},
"created": "2025-10-27T00:00:00Z"
}Remove the pin request. This unpins the corresponding CID from the service's nodes.
| Code | Meaning |
|---|---|
| 200 | OK |
| 201 | Created |
| 204 | No Content |
| 400 | Bad Request |
| 401 | Unauthorized |
| 404 | Not Found |
| 500 | Internal Server Error |
| Field | Type | Description |
|---|---|---|
| cid | string | The IPFS content identifier |
| name | string | Optional name for the pin |
| origins | array[string] | Multiaddresses where content was originally found |
| meta | object | Arbitrary key-value metadata provided by the user |
| Field | Type | Description |
|---|---|---|
| requestid | string | Unique identifier for the pin request |
| status | string | One of queued, pinning, pinned, failed |
| created | string | ISO 8601 timestamp when pin request was created |
| pin | object | The pin object |
| delegates | array[string] | Multiaddresses of nodes storing this content |
curl -X POST https://api.pinion.io/pins \
-H "Authorization: Bearer $PINION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"cid": "bafybeigdyrztp...",
"name": "my-data"
}'curl -H "Authorization: Bearer $PINION_TOKEN" \
https://api.pinion.io/pins?status=pinnedIf configured, the service can notify your endpoint whenever pin status changes.
POST to your webhook URL with payload:
{
"requestid": "8f3e4dc1-...-9ef1",
"status": "pinned",
"cid": "bafybeigdyrztp..."
}| Tier | Requests per Minute |
|---|---|
| Free | 60 |
| Pro | 600 |
| Enterprise | Custom |
When the rate limit is exceeded, the service returns:
{
"error": "rate_limit_exceeded",
"message": "Too many requests, please wait before retrying."
}| Error Code | Description |
|---|---|
| invalid_cid | The CID format is invalid |
| pin_not_found | The specified pin does not exist |
| quota_exceeded | Storage quota has been reached |
| unauthorized | Invalid or missing token |
The IPFS Gateway API provides HTTP access to content stored on the InterPlanetary File System (IPFS). It allows clients to retrieve content by its CID or path and supports both raw data streaming and browser-friendly delivery.
The API follows the IPFS Gateway specification and supports immutable (/ipfs/) and mutable (/ipns/) namespaces.
Public gateways may not require authentication. For private or usage-limited gateways, authenticate using a Bearer token:
Fetch immutable content identified by the CID.
GET /ipfs/bafybeigdyrztp... HTTP/1.1 Host: gateway.pinion.io Accept: */*
Returns the raw file or block associated with the CID. Content-Type depends on the data (e.g. application/octet-stream, text/html, application/json, etc.)
HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 14 Hello, IPFS!
Retrieve a specific file or subdirectory inside a DAG or UnixFS directory.
Returns the content of logo.png as stored within the directory DAG.
Resolve mutable content published via IPNS.
Resolves to the latest content published under that key.
Retrieve only headers and metadata about a CID, without downloading the body.
HTTP/1.1 200 OK Content-Type: application/octet-stream X-Ipfs-Path: /ipfs/bafybeigdyrztp... X-Ipfs-Size: 12345
Supports HTTP Range requests for partial retrieval.
GET /ipfs/bafybeigdyrztp... HTTP/1.1 Range: bytes=0-1023
HTTP/1.1 206 Partial Content Content-Range: bytes 0-1023/4096
When the CID references a directory DAG, the gateway returns an HTML or JSON directory listing.
<!DOCTYPE html>
<html>
<head><title>Index of /ipfs/bafybeigdyrztp...</title></head>
<body>
<h1>Index of /ipfs/bafybeigdyrztp...</h1>
<ul>
<li><a href="file.txt">file.txt</a></li>
<li><a href="images/">images/</a></li>
</ul>
</body>
</html>Add header Accept: application/json:
{
"type": "directory",
"cid": "bafybeigdyrztp...",
"entries": [
{"Name": "file.txt", "CID": "bafybeib...", "Size": 1024, "Type": "file"},
{"Name": "images", "CID": "bafybeid...", "Type": "directory"}
]
}| Accept Header | Response Type |
|---|---|
| application/json | JSON DAG node |
| text/html | Rendered HTML directory listing |
| application/octet-stream | Raw block or file content |
If the gateway is linked with your Pinning Service account, you may request on-demand pinning via query parameter:
GET /ipfs/bafybeigdyrztp...?pin=true Authorization: Bearer <API_TOKEN>
Response headers will include:
| Code | Meaning |
|---|---|
| 200 | OK |
| 202 | Accepted (content is being fetched or pinned) |
| 206 | Partial Content |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 500 | Internal Server Error |
| 504 | Gateway Timeout (upstream content unavailable) |
| Header | Description |
|---|---|
| X-Ipfs-Path | The resolved IPFS path |
| X-Ipfs-Roots | Root CID(s) of the DAG |
| X-Ipfs-Size | Size of the object in bytes (if known) |
| X-Pinion-Cache | HIT or MISS if the gateway caches responses |
| X-Content-Type-Options | Typically set to nosniff |
Pinion Gateway caches content on first access. Subsequent requests for the same CID are served directly from cache if available.
| Tier | Cache Duration | Notes |
|---|---|---|
| Free | 24 hours | May be evicted early under load |
| Pro | 7 days | Cached across all edge regions |
| Enterprise | Custom | Includes private caching and origin replication |
| Error Code | Description |
|---|---|
| invalid_cid | The CID format is invalid |
| not_found | The requested content could not be resolved |
| timeout | Upstream node did not respond in time |
| forbidden | Access to private gateway content denied |
| internal_error | Unexpected backend failure |
curl -H "Accept: application/json" \
https://gateway.pinion.io/ipfs/bafybeigdyrztp...| Tier | Requests per Minute | Max Response Size |
|---|---|---|
| Free | 60 | 50 MB |
| Pro | 600 | 500 MB |
| Enterprise | Custom | Unlimited |
When rate limit exceeded:
{
"error": "rate_limit_exceeded",
"message": "Too many requests, please wait before retrying."
}The Pinion Upload API allows clients to upload files or CAR (Content Addressable Archive) files, pin them to IPFS, and receive pin status updates. Each upload request may produce one or multiple pins, each with a unique status.
Uploads a file or CAR archive for pinning.
Content-Type (required):
application/vnd.ipld.carapplication/octet-stream)| Parameter | Type | Required | Description |
|---|---|---|---|
| format | string | optional | If set to car, the server treats the body as a CAR file regardless of Content-Type. |
| name | string | optional | A human-readable name for the pin. If multiple roots are produced, names will be automatically suffixed. |
The raw file data to pin. Either a single file or a CAR archive, depending on Content-Type or format.
Requests must be authenticated. The server identifies the user via context, typically through cookies or an Authorization header (see your account service integration). Unauthorized requests will return 401 Unauthorized.
Returns the status of the pinned content.
Single root pinned:
{
"requestid": "uuid-string",
"status": "PINNING",
"created": "2025-10-27T01:23:45.678Z",
"pin": {
"cid": "bafybeib...",
"name": "myfile"
}
}Multiple roots pinned:
Returns an array of pin statuses:
[
{
"requestid": "uuid-string-1",
"status": "PINNING",
"created": "2025-10-27T01:23:45.678Z",
"pin": {
"cid": "bafybeib1...",
"name": "myfile-root-0"
}
},
{
"requestid": "uuid-string-2",
"status": "PINNING",
"created": "2025-10-27T01:23:45.678Z",
"pin": {
"cid": "bafybeib2...",
"name": "myfile-root-1"
}
}
]| Status Code | Condition |
|---|---|
| 401 Unauthorized | User authentication failed. |
| 500 Internal Server Error | Failed to process the upload, store pin status, or send pin messages. The response body may include server error details. |
-root-N to the provided name for clarity.Pinion's GitHub integration allows developers to automatically upload build artifacts and host decentralized application (dApp) frontends on IPFS directly from GitHub Actions or workflows. This enables seamless CI/CD for static sites, frontends, and other assets, while ensuring persistence and availability via Pinion's pinning service.
Upload build outputs (e.g., dist/, build/) from GitHub workflows directly to Pinion.
Pinion hosts pinned frontend files and provides a content-addressable URL for accessing the application.
Handles multi-file builds (like Webpack or Vite outputs) by pinning each root CID separately.
Each upload produces pin status messages for monitoring via Pinion's dashboard or webhooks.
Create a .github/workflows/pinion-upload.yml in your repository:
name: Pinion Upload
on:
push:
branches:
- main
jobs:
upload:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Build project
run: |
npm install
npm run build # Outputs files to ./dist
- name: Upload artifacts to Pinion
uses: actions/http-client@v1
with:
url: http://pinion.build/upload/api/v1/
method: POST
headers: |
Content-Type: application/octet-stream
Authorization: Bearer ${{ secrets.PINION_API_TOKEN }}
body: ./dist # Path to your build outputNote: Replace ./dist with the folder containing your frontend build artifacts.
| Parameter | Description |
|---|---|
| Content-Type | application/octet-stream for normal files or application/vnd.ipld.car for CAR archives. |
| Authorization | Bearer <PINION_API_TOKEN> for authentication. |
| name (query) | Optional human-readable name for the pinned build. |
After pinning, Pinion provides a content-addressable URL for your frontend:
<root-cid> corresponds to the root CID returned in the pin status JSON.
Each time you push a new build, a new root CID is generated. Use your workflow to update references automatically.
-root-N to each pin name for clarity.This integration enables fully automated, GitHub-native deployment of dApps and pinned assets with IPFS persistence, reducing manual upload overhead and simplifying CI/CD pipelines.