Skip to main content
Payment Instructions are the core mechanism for monetizing private IPFS content through the x402 protocol. You define payment requirements, attach them to your private files, and receive payments directly to your wallet when requesters access your content. This guide covers how to create, manage, and use Payment Instructions to monetize your content.

Prerequisites

  • x402 feature flag enabled on your Pinata account
  • Authentication with appropriate permissions (OrgFilesRead or OrgFilesWrite)
  • Private files uploaded to Pinata IPFS

Understanding Payment Instructions

A Payment Instruction is a reusable configuration that defines:
  • Payment requirements - The amount, token, and recipient for payments
  • Network configuration - Which blockchain network to use
  • Metadata - Name and description for organization
The payment_requirements field is an array for future extensibility. Currently, only the first payment requirement in the array is processed by the gateway.

Payment Instruction Structure

{
  "id": "019a2b6a-adc5-7608-9ef2-2666248a60d6",
  "version": 1,
  "payment_requirements": [
    {
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "pay_to": "0x6135561038E7C676473431842e586C8248276AED",
      "network": "base",
      "description": "Premium content access",
      "max_amount_required": "10000"
    }
  ],
  "name": "Premium Content",
  "description": "Access to premium files",
  "created_at": "2025-10-28T15:23:22.951382Z"
}
The version field is automatically managed by Pinata and increments with each update. You don’t need to set this field when creating or updating payment instructions.

Networks and Tokens

Currently supported configurations:

Base Mainnet (Production)

  • Network: base
  • USDC Token Address: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
  • Use for: Production monetization

Base Sepolia (Testing)

  • Network: base-sepolia
  • USDC Token Address: 0x036CbD53842c5426634e7929541eC2318f3dCF7e
  • Use for: Testing payment flows

Complete Workflow

Step 1: Upload Private Content

First, upload your file as private to Pinata:
curl -X POST https://uploads.pinata.cloud/v3/files \
  -H "Authorization: Bearer YOUR_JWT" \
  -F "[email protected]" \
  -F "network=private"
Important: The file must be uploaded to the private network to be monetized with x402.

Step 2: Create Payment Instruction

Create a payment instruction with your desired requirements:
curl -X POST https://api.pinata.cloud/v3/x402/payment_instructions \
  -H "Authorization: Bearer YOUR_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Premium PDF Access",
    "description": "One-time payment for PDF access",
    "payment_requirements": [
      {
        "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        "pay_to": "0x6135561038E7C676473431842e586C8248276AED",
        "network": "base",
        "description": "Access fee",
        "max_amount_required": "10000"
      }
    ]
  }'

Step 3: Attach CID to Payment Instruction

Link your private file to the payment instruction:
curl -X PUT https://api.pinata.cloud/v3/x402/payment_instructions/{instruction_id}/cids/{cid} \
  -H "Authorization: Bearer YOUR_JWT"

Step 4: Share x402 Gateway URL

Your content is now monetized and accessible at:
https://your-gateway.mypinata.cloud/x402/cid/{cid}

Managing Payment Instructions

Listing Instructions

View all your payment instructions with pagination:
curl -X GET "https://api.pinata.cloud/v3/x402/payment_instructions?limit=20" \
  -H "Authorization: Bearer YOUR_JWT"
Filter by specific criteria:
  • ?cid=bafkreih... - Find instruction for a specific CID
  • ?name=Premium - Filter by name
  • ?id=019a2b6a... - Get specific instruction

Updating Instructions

Modify payment requirements for all attached CIDs:
curl -X PATCH https://api.pinata.cloud/v3/x402/payment_instructions/{id} \
  -H "Authorization: Bearer YOUR_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_requirements": [
      {
        "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        "pay_to": "0x6135561038E7C676473431842e586C8248276AED",
        "network": "base",
        "max_amount_required": "50000"
      }
    ]
  }'

Deleting Instructions

Before deleting, remove all CID attachments:
# 1. List attached CIDs
curl -X GET https://api.pinata.cloud/v3/x402/payment_instructions/{id}/cids \
  -H "Authorization: Bearer YOUR_JWT"

# 2. Remove each CID
curl -X DELETE https://api.pinata.cloud/v3/x402/payment_instructions/{id}/cids/{cid} \
  -H "Authorization: Bearer YOUR_JWT"

# 3. Delete the instruction
curl -X DELETE https://api.pinata.cloud/v3/x402/payment_instructions/{id} \
  -H "Authorization: Bearer YOUR_JWT"

CID Management

One-to-Many Relationship

  • One Payment Instruction can be attached to multiple CIDs
  • Each CID can only have one Payment Instruction at a time
  • Updating the instruction affects all attached CIDs

Managing CID Attachments

# List all CIDs for an instruction
curl -X GET https://api.pinata.cloud/v3/x402/payment_instructions/{instruction_id}/cids \
  -H "Authorization: Bearer YOUR_JWT"

# Add a CID
curl -X PUT https://api.pinata.cloud/v3/x402/payment_instructions/{instruction_id}/cids/{cid} \
  -H "Authorization: Bearer YOUR_JWT"

# Remove a CID
curl -X DELETE https://api.pinata.cloud/v3/x402/payment_instructions/{instruction_id}/cids/{cid} \
  -H "Authorization: Bearer YOUR_JWT"

Gateway Behavior

When a requester accesses your x402 gateway URL without payment, the gateway returns payment requirements:

Without Payment (402 Response)

{
  "x402Version": 1,
  "accepts": [
    {
      "scheme": "exact",
      "network": "base",
      "maxAmountRequired": "10000",
      "resource": "https://gateway/x402/cid/bafkreig...",
      "payTo": "0x6135561038E7C676473431842e586C8248276AED",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "extra": {
        "name": "USD Coin",
        "version": "2"
      }
    }
  ],
  "error": "Provide a valid X-Payment header to access this content"
}

With Valid Payment

The gateway:
  1. Validates the X-Payment header
  2. Verifies the payment proof
  3. Checks amount, recipient, and network match requirements
  4. Serves the private content

Best Practices

Payment Amounts

The max_amount_required uses USDC’s smallest unit. USDC has 6 decimals, so to convert USD to the token amount, multiply by 1,000,000:
USD Amountmax_amount_requiredCalculation
$0.01"10000"$0.01 × 1,000,000
$0.10"100000"$0.10 × 1,000,000
$1.00"1000000"$1.00 × 1,000,000
$5.00"5000000"$5.00 × 1,000,000
$10.00"10000000"$10.00 × 1,000,000
Formula: USD Amount × 1,000,000 = token amount Tips:
  • Consider transaction costs when setting minimum amounts
  • Test on Base Sepolia before deploying to mainnet

Instruction Organization

  • Use descriptive names for easy management
  • Group similar content under one instruction
  • Document your payment requirements clearly

Security Considerations

  • Only private files can be monetized
  • Ensure your pay_to address is correct. You receive payments directly to this address.
  • Test payment flows on testnet first
  • Monitor your gateway analytics

Troubleshooting

Common Issues

409 Conflict when deleting instruction
  • Solution: Remove all CID attachments first
400 Bad Request when creating instruction
  • Check asset and pay_to addresses start with 0x
  • Verify network is either base or base-sepolia
  • Ensure max_amount_required is provided
404 Not Found when accessing CID
  • Verify the CID exists and is private
  • Check the CID is attached to a payment instruction
  • Ensure the gateway URL format is correct

API Reference

For detailed API specifications, see: