Pinion Documentation

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.

Pinning Service

IPFS Pinning Service API Documentation

Overview

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.

Base URL

https://api.pinion.io

Authentication

All endpoints require authentication using a Bearer token.

Example
Authorization: Bearer <API_TOKEN>

To create or manage API tokens, visit your Account Settings.

Endpoints

List Pins
GET /pins

Retrieve a list of pinned or pinning requests.

Query Parameters
NameTypeDescription
cidstringFilter by specific CID (exact match or comma-separated list)
namestringFilter by user-defined pin name
statusstringFilter by pin status (queued, pinning, pinned, failed)
limitintegerMaximum number of results to return
beforestringReturn results created before this ISO 8601 timestamp
afterstringReturn results created after this ISO 8601 timestamp
Response
{
  "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"]
    }
  ]
}
Add a Pin
POST /pins

Create a new pin request.

Request Body
{
  "cid": "bafybeigdyrztp...",
  "name": "project-backup",
  "origins": ["/ip4/203.0.113.10/tcp/4001/p2p/QmOrigin"],
  "meta": {"environment": "production"}
}
Response
{
  "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"
}
Get Pin by ID
GET /pins/{requestid}

Retrieve metadata and status for a specific pin request.

Response
{
  "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 a Pin
POST /pins/{requestid}

Replace the pin for a given request ID with a new CID or metadata.

Request Body
{
  "cid": "bafybeicx...",
  "name": "project-backup-v2"
}
Response
{
  "requestid": "8f3e4dc1-...-9ef1",
  "status": "queued",
  "pin": {
    "cid": "bafybeicx...",
    "name": "project-backup-v2"
  },
  "created": "2025-10-27T00:00:00Z"
}
Remove a Pin
DELETE /pins/{requestid}

Remove the pin request. This unpins the corresponding CID from the service's nodes.

Response
204 No Content

Status Codes

CodeMeaning
200OK
201Created
204No Content
400Bad Request
401Unauthorized
404Not Found
500Internal Server Error

Data Model

Pin Object
FieldTypeDescription
cidstringThe IPFS content identifier
namestringOptional name for the pin
originsarray[string]Multiaddresses where content was originally found
metaobjectArbitrary key-value metadata provided by the user
PinStatus Object
FieldTypeDescription
requestidstringUnique identifier for the pin request
statusstringOne of queued, pinning, pinned, failed
createdstringISO 8601 timestamp when pin request was created
pinobjectThe pin object
delegatesarray[string]Multiaddresses of nodes storing this content

Examples

Pin a File with curl
curl -X POST https://api.pinion.io/pins \
  -H "Authorization: Bearer $PINION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "cid": "bafybeigdyrztp...",
        "name": "my-data"
      }'
List All Pinned CIDs
curl -H "Authorization: Bearer $PINION_TOKEN" \
     https://api.pinion.io/pins?status=pinned

Webhooks (Optional Feature)

If 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..."
}

Rate Limits

TierRequests per Minute
Free60
Pro600
EnterpriseCustom

When the rate limit is exceeded, the service returns:

{
  "error": "rate_limit_exceeded",
  "message": "Too many requests, please wait before retrying."
}

Errors

Error CodeDescription
invalid_cidThe CID format is invalid
pin_not_foundThe specified pin does not exist
quota_exceededStorage quota has been reached
unauthorizedInvalid or missing token

Gateway API

IPFS Gateway API Documentation

Overview

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.

Base URL

https://gateway.pinion.io

Authentication

Public gateways may not require authentication. For private or usage-limited gateways, authenticate using a Bearer token:

Authorization: Bearer <API_TOKEN>

Endpoints

Retrieve by CID
GET /ipfs/{cid}

Fetch immutable content identified by the CID.

Example
GET /ipfs/bafybeigdyrztp... HTTP/1.1
Host: gateway.pinion.io
Accept: */*
Response

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.)

Example Response
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 14

Hello, IPFS!
Retrieve by Path
GET /ipfs/{cid}/{path}

Retrieve a specific file or subdirectory inside a DAG or UnixFS directory.

Example
GET /ipfs/bafybeigdyrztp.../images/logo.png

Returns the content of logo.png as stored within the directory DAG.

Mutable Namespace (IPNS)
GET /ipns/{peerid_or_domain}

Resolve mutable content published via IPNS.

Example
GET /ipns/k51qzi5uqu5dhiw1m07xv3t...

Resolves to the latest content published under that key.

Metadata Only
HEAD /ipfs/{cid}

Retrieve only headers and metadata about a CID, without downloading the body.

Example
curl -I https://gateway.pinion.io/ipfs/bafybeigdyrztp...
Response
HTTP/1.1 200 OK
Content-Type: application/octet-stream
X-Ipfs-Path: /ipfs/bafybeigdyrztp...
X-Ipfs-Size: 12345
Range Requests

Supports HTTP Range requests for partial retrieval.

Example
GET /ipfs/bafybeigdyrztp... HTTP/1.1
Range: bytes=0-1023
Response
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/4096
Directory Listings

When the CID references a directory DAG, the gateway returns an HTML or JSON directory listing.

Example
curl https://gateway.pinion.io/ipfs/bafybeigdyrztp...
Response (HTML)
<!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>
Response (JSON)

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"}
  ]
}

Content-Type Negotiation

Accept HeaderResponse Type
application/jsonJSON DAG node
text/htmlRendered HTML directory listing
application/octet-streamRaw block or file content

Pinning via Gateway (Optional Feature)

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:

X-Pinion-Pin-Status: pinned

Status Codes

CodeMeaning
200OK
202Accepted (content is being fetched or pinned)
206Partial Content
400Bad Request
401Unauthorized
403Forbidden
404Not Found
500Internal Server Error
504Gateway Timeout (upstream content unavailable)

Response Headers

HeaderDescription
X-Ipfs-PathThe resolved IPFS path
X-Ipfs-RootsRoot CID(s) of the DAG
X-Ipfs-SizeSize of the object in bytes (if known)
X-Pinion-CacheHIT or MISS if the gateway caches responses
X-Content-Type-OptionsTypically set to nosniff

Caching

Pinion Gateway caches content on first access. Subsequent requests for the same CID are served directly from cache if available.

TierCache DurationNotes
Free24 hoursMay be evicted early under load
Pro7 daysCached across all edge regions
EnterpriseCustomIncludes private caching and origin replication

Errors

Error CodeDescription
invalid_cidThe CID format is invalid
not_foundThe requested content could not be resolved
timeoutUpstream node did not respond in time
forbiddenAccess to private gateway content denied
internal_errorUnexpected backend failure

Examples

Retrieve File
curl https://gateway.pinion.io/ipfs/bafybeigdyrztp...
Retrieve as JSON DAG
curl -H "Accept: application/json" \
     https://gateway.pinion.io/ipfs/bafybeigdyrztp...
Retrieve via IPNS
curl https://gateway.pinion.io/ipns/example.com
Partial Download
curl -r 0-4095 https://gateway.pinion.io/ipfs/bafybeigdyrztp...

Rate Limits

TierRequests per MinuteMax Response Size
Free6050 MB
Pro600500 MB
EnterpriseCustomUnlimited

When rate limit exceeded:

{
  "error": "rate_limit_exceeded",
  "message": "Too many requests, please wait before retrying."
}

Upload Service

Pinion Upload API v1

Overview

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.

Base URL

http://pinion.build/upload/api/v1/

Endpoint: POST /

Uploads a file or CAR archive for pinning.

Request
Headers

Content-Type (required):

  • For a CAR file: application/vnd.ipld.car
  • For regular files: any other valid MIME type (e.g., application/octet-stream)
Query Parameters
ParameterTypeRequiredDescription
formatstringoptionalIf set to car, the server treats the body as a CAR file regardless of Content-Type.
namestringoptionalA human-readable name for the pin. If multiple roots are produced, names will be automatically suffixed.
Body

The raw file data to pin. Either a single file or a CAR archive, depending on Content-Type or format.

Authentication

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.

Response
Successful Response (200 OK)

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"
    }
  }
]
Error Responses
Status CodeCondition
401 UnauthorizedUser authentication failed.
500 Internal Server ErrorFailed to process the upload, store pin status, or send pin messages. The response body may include server error details.
Behavior
  • The server processes the uploaded data and extracts one or more root CIDs.
  • Each root receives a unique requestid and initial status of PINNING.
  • Pin statuses are stored in the internal datastore (docstore) for tracking.
  • Each pin status is encoded and published to a Pub/Sub topic to notify other services.
  • The API returns all pin statuses in the response.
Notes
  • If multiple roots are generated from a single upload, the server automatically appends -root-N to the provided name for clarity.
  • The requestid can be used to query pin status from downstream services or dashboards.
  • All timestamps are returned in ISO 8601 UTC format.

GitHub Integration

GitHub Integration with Pinion

Overview

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.

Base Pinion API URL

http://pinion.build/upload/api/v1/

Features

Automatic artifact pinning

Upload build outputs (e.g., dist/, build/) from GitHub workflows directly to Pinion.

dApp frontend hosting

Pinion hosts pinned frontend files and provides a content-addressable URL for accessing the application.

Multi-root support

Handles multi-file builds (like Webpack or Vite outputs) by pinning each root CID separately.

Status tracking

Each upload produces pin status messages for monitoring via Pinion's dashboard or webhooks.

Prerequisites

  • A Pinion account with an API token or credentials.
  • A GitHub repository for your project.
  • Optional: GitHub Secrets configured with your Pinion API token.

Example Workflow: Upload Build Artifacts

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 output

Note: Replace ./dist with the folder containing your frontend build artifacts.

Parameters
ParameterDescription
Content-Typeapplication/octet-stream for normal files or application/vnd.ipld.car for CAR archives.
AuthorizationBearer <PINION_API_TOKEN> for authentication.
name (query)Optional human-readable name for the pinned build.

Hosting dApp Frontends

After pinning, Pinion provides a content-addressable URL for your frontend:

https://pinion.build/ipfs/<root-cid>/

<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.

Handling Multiple Roots
  • If your build produces multiple roots, Pinion will append -root-N to each pin name for clarity.
  • Your workflow should capture each root CID to generate URLs for hosted assets.

Monitoring Pin Status

  • Each upload returns a JSON object (or array for multiple roots) with requestid, status, and pin.cid.
  • Use the requestid to track pin progress or trigger downstream workflows.
Recommended Workflow Enhancements
  • CAR upload: For large builds, package your files as a CAR file to ensure deterministic pinning.
  • Caching: Store previous root CIDs in workflow artifacts to skip re-uploading unchanged files.
  • Notifications: Subscribe to Pinion Pub/Sub messages for automated deployment triggers.

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.