Get started with Pinion in three simple steps:
Sign in to your Dashboard and navigate to your profile settings to create an API token. Keep it secure!
Use curl for quick tests, or install an IPFS pinning service client library for your language of choice.
Try pinning content with a simple curl command:
curl -X POST https://<environment>.pinion.build/pinning/api/v1/pins \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"cid": "bafybeigdyrzt...", "name": "my-first-pin"}'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 |
The Pinion Gateway provides HTTP access to content stored in the IPFS blockstore by CID. It implements the IPFS HTTP Gateway specification, including full content-type negotiation via the Accept header.
Because Pinion uses a shared blockstore, content uploaded through the Upload Service is immediately retrievable through the Gateway — even before the worker has finished processing the pin request.
Two authentication methods are supported, routed at different paths:
| Method | Path prefix | Required |
|---|---|---|
| JWT Bearer token | /gateway/api/v1/ | Gateway Service group membership |
| OAuth2 session (browser) | /gateway/web/ | Active browser session cookie |
Retrieve content by CID. Optionally traverse into a UnixFS directory using a path suffix.
| Parameter | Type | Description |
|---|---|---|
| cid | path (required) | IPFS Content Identifier (CIDv0 or CIDv1) |
| path | path (optional) | Sub-path within a UnixFS directory (e.g. /index.html) |
Use the Accept header to request a specific response format:
| Accept header | Response |
|---|---|
| (default) | Deserialized content (file bytes, HTML for directories) |
| application/vnd.ipld.car | CAR archive of the DAG rooted at the CID |
| application/vnd.ipld.raw | Raw block bytes for the exact CID |
| application/json | JSON representation (for IPLD JSON nodes) |
Responses include standard HTTP caching headers. Because IPFS content is content-addressed and immutable, responses for a given CID are safe to cache indefinitely. Cache-Control: public, max-age=29030400, immutable is set by the gateway for resolved content.
Fetch a file by CID (JWT):
curl https://<environment>.pinion.build/gateway/api/v1/ipfs/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi \ -H "Authorization: Bearer YOUR_TOKEN"
Download a CAR archive of a DAG:
curl https://<environment>.pinion.build/gateway/api/v1/ipfs/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Accept: application/vnd.ipld.car" \ -o content.car
Fetch a file within a directory CID:
curl https://<environment>.pinion.build/gateway/api/v1/ipfs/bafybeid.../index.html \ -H "Authorization: Bearer YOUR_TOKEN"
Gateway bandwidth is metered and billed according to your subscription plan. See the Pricing page for details.
The Upload Service accepts files and CAR archives, writes them directly into the shared IPFS blockstore, and creates a pin request for asynchronous processing by the worker cluster. Content is immediately available via the Gateway upon upload — before the pin is confirmed.
Two upload formats are supported:
| Method | Path prefix | Required |
|---|---|---|
| JWT Bearer token | /upload/api/v1/ | Upload Service group membership |
| OAuth2 session (browser) | /upload/web/ | Active browser session cookie |
Upload a file or CAR archive to IPFS.
| Name | Type | Description |
|---|---|---|
| format | string | Set to car to treat the body as a CAR archive. Alternatively, set Content-Type: application/vnd.ipld.car. |
| name | string | Human-readable label for the pin. For CAR files with multiple roots, -root-0, -root-1, … are appended automatically. |
| Content-Type | Body |
|---|---|
| multipart/form-data | Form field file containing the file bytes |
| application/octet-stream | Raw file bytes in the request body |
| application/vnd.ipld.car | CAR archive bytes in the request body |
Returns a PinStatus object on success, or an array of PinStatus objects when a CAR file contains multiple roots.
// Single root
{
"requestid": "550e8400-e29b-41d4-a716-446655440000",
"status": "pinning",
"created": "2025-01-15T12:00:00Z",
"pin": {
"cid": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"name": "my-file"
}
}After upload, the pin enters pinning status. A worker node picks up the request from the pubsub queue, verifies the content is present in the blockstore, and transitions the pin to pinned. Because content is written directly to the shared blockstore on upload, it is retrievable via the Gateway immediately — not only after pinning completes.
Upload a regular file (multipart):
curl -X POST https://<environment>.pinion.build/upload/api/v1/ \ -H "Authorization: Bearer YOUR_TOKEN" \ -F "file=@./myfile.txt" \ -G --data-urlencode "name=myfile"
Upload raw bytes (octet-stream):
curl -X POST https://<environment>.pinion.build/upload/api/v1/?name=myfile \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/octet-stream" \ --data-binary @./myfile.txt
Upload a CAR archive (via Content-Type):
curl -X POST https://<environment>.pinion.build/upload/api/v1/?name=my-dag \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/vnd.ipld.car" \ --data-binary @./content.car
Upload a CAR archive (via query param, useful when Content-Type cannot be set):
curl -X POST "https://<environment>.pinion.build/upload/api/v1/?format=car&name=my-dag" \ -H "Authorization: Bearer YOUR_TOKEN" \ --data-binary @./content.car
Pinion integrates with GitHub as a GitHub App. Once installed on your account or organization, Pinion monitors your repositories and automatically pins content to IPFS based on a configuration file you commit to each repository.
No CI pipeline changes are needed. Pinion responds directly to GitHub webhook events.
Green checkmarks on every commit
Pinion posts a commit status to GitHub under the pinion/ipfs context. When pinning succeeds, the status turns green and includes the IPFS CID. Clicking Details opens the pinned content directly in the Pinion gateway.
docs/, dist/) independently.*.tar.gz), and control whether auto-generated source code archives are included.pinion.build.yaml file to the root of any repository you want Pinion to monitor.pinion.build.yamlPlace this file at the root of your repository. Sections you omit are ignored.
version: 1
# Release asset pinning - supports pattern matching
release_assets:
enabled: true
include_source_code: true
patterns:
- "*.txt"
- "*.tar.gz"
# Directory monitoring - supports multiple paths and branch selection
subdirectories:
enabled: true
branch: "main" # Git branch to monitor (default: "main")
paths:
- "docs/" # Pin documentation directory
- "static/" # Pin static assets
- "dist/" # Pin build output
- "data/" # Pin data filesrelease_assets| Field | Type | Description |
|---|---|---|
| enabled | bool | Pin assets when a release is published |
| patterns | string[] | Glob patterns to filter which assets are pinned. If omitted, all assets are pinned. |
| include_source_code | bool | Whether to include the auto-generated source code archives (source.zip, source.tar.gz) that GitHub attaches to every release. |
subdirectories| Field | Type | Description |
|---|---|---|
| enabled | bool | Pin the listed paths on each push |
| branch | string | Branch to monitor. Defaults to main. |
| paths | string[] | Repository paths to pin. Each path is pinned independently and receives its own CID. |
Each webhook event Pinion receives is recorded with a status and any processing messages. You can review these events from your GitHub Events page to diagnose configuration issues or confirm that pins were created successfully.