API Reference - alxspiker/Pi-Network-Developer-Docs GitHub Wiki

🔌 Pi Network API Reference

Complete reference for Pi Network REST API endpoints

Integrate with Pi Network's backend services for authentication, payments, and user data

📋 Table of Contents


🚀 Quick Start

💡 New to Pi Network APIs? Start here for the essentials

🔗 Base URL

https://api.minepi.com/v2/

📝 Basic Request Structure

All API requests to Pi Network follow this pattern:

curl -X GET "https://api.minepi.com/v2/ENDPOINT" \
     -H "Authorization: METHOD YOUR_TOKEN" \
     -H "Content-Type: application/json"

🔐 Authorization Methods

⚠️ Security Notice: All API requests require proper authentication. Choose the method based on your use case.

🔑 Method 📝 Use Case 🔧 Header Format 📚 Documentation
Access Token User-specific operations Authorization: Bearer YOUR_TOKEN 📖 Guide
Server API Key App-level operations Authorization: YOUR_API_KEY 📖 Guide

🎯 Quick Reference

When to use Access Tokens:

  • Getting user profile data
  • User-specific payment queries
  • Any operation requiring user consent

When to use API Keys:

  • Server-side payment processing
  • App-level statistics
  • Administrative operations

👤 User Endpoints

🔍 GET /me

📋 Get authenticated user information

🔧 Usage in Your Application

Implementation Notes:

  • Always validate the access token before processing requests
  • Handle expired tokens gracefully with proper error responses
  • Store sensitive operations server-side, never in frontend JavaScript

🎯 Purpose

This endpoint provides verified Pioneer information for the authenticated user.

  • Get Pioneer UID - Unique app-specific identifier
  • Access Username - Pi Network username (requires username scope)
  • Verify Authentication - Confirm user identity

📝 Example Implementation

Python Example
import requests

# Replace with actual token from frontend authentication
access_token = "accessToken_Obtained_from_App_Frontend"
headers = {"Authorization": f"Bearer {access_token}"}

response = requests.get("https://api.minepi.com/v2/me", headers=headers)

if response.status_code == 200:
    user_data = response.json()
    print("✅ Authentication successful!")
    print(f"Pioneer UID: {user_data['uid']}")
    
    # Username only available if 'username' scope was granted
    if 'username' in user_data:
        print(f"Pioneer Username: {user_data['username']}")
else:
    print(f"❌ Error {response.status_code}: {response.text}")
JavaScript Example
// Frontend - after Pi.authenticate()
async function getUserInfo(accessToken) {
  try {
    const response = await fetch('https://api.minepi.com/v2/me', {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
      }
    });

    if (response.ok) {
      const userData = await response.json();
      console.log('✅ User authenticated:', userData);
      return userData;
    } else {
      console.error('❌ Authentication failed:', response.status);
    }
  } catch (error) {
    console.error('❌ Request failed:', error);
  }
}
cURL Example
curl -X GET "https://api.minepi.com/v2/me" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -H "Content-Type: application/json"

📊 Response Format

{
  "uid": "unique_pioneer_identifier",
  "username": "pioneer_username"  // Only if 'username' scope granted
}

else: print("Error:", response.status_code) print(response.text)


**Example Code: (JavaScript)**
```javascript
const baseUrl = "https://api.minepi.com/v2";
const accessToken = "accessToken_Obtained_from_App_Frontend"; 

async function fetchPioneerData() {
  try {
    const response = await fetch(`${baseUrl}/me`, {
      headers: {
        Authorization: `Bearer ${accessToken}` 
      }
    });

    if (response.ok) {
      const userDTO = await response.json();
      console.log("Success!");
      console.log("Pioneer UID:", userDTO.uid);
      console.log("Pioneer Username:", userDTO.username); // If 'username' scope was granted
    } else {
      console.error("Error:", response.status, response.statusText);
    }
  } catch (error) {
    console.error("Error fetching Pioneer data:", error);
  }
}

// Call the function to fetch data
fetchPioneerData(); 

/payments

These endpoints provide information and allow management of payments within your app. Important: Use the client-side Pi SDK to initiate new payments.

Base URL: https://api.minepi.com/v2/payments

Authorization: Server API Key (Key Authorization) See Documentation

Returns: PaymentDTO object See Documentation

Important Note: It sounds like there might be additional endpoints nested under /payments for actions like approving or canceling. If so, please provide those specifics so we can create documentation tailored to them.

Example Code (Python)

import requests

api_key = "your_server_api_key"  # Replace with your key
header = {"Authorization": "Key " + api_key}
response = requests.get("[https://api.minepi.com/v2/payments](https://api.minepi.com/v2/payments)", headers=header)

if response.status_code == 200:
    payments = response.json()  # Assuming an array of PaymentDTOs
    print("Success! Retrieved Payments:")
    for payment in payments:
        print(payment['identifier'], payment['status']) 
else:
    print("Error:", response.status_code)
    print(response.text) 

Example Code (JavaScript)

async function fetchPayments() {
  const serverApiKey = "your_server_api_key";

  try {
    const response = await fetch(`${baseUrl}/payments`, {
      headers: {
        Authorization: `Key ${serverApiKey}`,
      },
    });

    if (response.ok) {
      const payments = await response.json();
      console.log("Success! Retrieved Payments:");
      payments.forEach((payment) => {
        console.log(payment.identifier, payment.status);
      });
    } else {
      console.error("Error:", response.status, response.statusText);
    }
  } catch (error) {
    console.error("Error fetching payments:", error);
  }
}

// Call the function to fetch payments
fetchPayments();

/payments/approve

This endpoint enables server-side approval of a pending Pi payment, a required step before the Pioneer can finalize the transaction on the blockchain.

URL: POST https://api.minepi.com/v2/payments/{payment_id}/approve

Authorization: Server API Key (Key Authorization) See Documentation

Returns: PaymentDTO object See Documentation

Important Notes

  • Obtain payment_id: The payment_id is provided as an argument within the onReadyForServerApproval callback function of the Pi App Platform SDK.
  • Asynchronous Process: Approving a payment on the server side does not instantly complete the transaction. The Pioneer must still confirm it within the Pi Browser.

Example Code (Python)

import requests

api_key = "your_server_api_key" 
header = {"Authorization": "Key " + api_key}

def handle_payment_approval(payment_id):  
    response = requests.post(f"[https://api.minepi.com/v2/payments/](https://api.minepi.com/v2/payments/){payment_id}/approve", headers=header)

    if response.status_code == 200:
        print("Payment approved on server!")
        # Potentially update your application's UI or database
    else:
        print("Error approving payment:", response.status_code)
        print(response.text) 

# ... (Inside your code handling the 'onReadyForServerApproval' callback) 
handle_payment_approval(payment_id) 

Example Code: (JavaScript)

const baseUrl = "https://api.minepi.com/v2";
const serverApiKey = "your_server_api_key";

async function handlePaymentApproval(paymentId) {
  try {
    const response = await fetch(`${baseUrl}/payments/${paymentId}/approve`, {
      method: "POST",
      headers: {
        Authorization: `Key ${serverApiKey}`,
      },
    });

    if (response.ok) {
      console.log("Payment approved on server!");
      // Potentially update your application's UI or database
    } else {
      console.error("Error approving payment:", response.status, response.statusText);
      const errorText = await response.text(); // Get error message from response
      console.error(errorText); 
    }
  } catch (error) {
    console.error("Error handling payment approval:", error);
  }
}

// ... (Inside your code handling the 'onReadyForServerApproval' callback) 
handlePaymentApproval(payment_id);  // Assuming you have the payment_id

/payments/complete

This endpoint finalizes a Pi payment on the server side by providing the blockchain transaction ID (txID). This marks the payment process as fully completed.

URL: POST https://api.minepi.com/v2/payments/{payment_id}/complete

Authorization: Server API Key (Key Authorization) See Documentation

Returns: PaymentDTO object See Documentation

Workflow

  1. Obtain txID: The txID is provided within the onReadyForServerCompletion callback function of the Pi App Platform SDK.
  2. Send to Server: Pass the txID from the frontend to your application's backend.
  3. Call Endpoint: Use this endpoint, providing the payment_id and txID to signal completion to the Pi Network servers.

Example Code (Python)

import requests

api_key = "your_server_api_key" 
header = {"Authorization": "Key " + api_key}

def complete_payment(payment_id, txid):
    data = {'txid': txid} 
    response = requests.post(f"[invalid URL removed]", headers=header, json=data) 

    if response.status_code == 200:
        print("Payment successfully completed!")
    else:
        print("Error completing payment:", response.status_code)
        print(response.text) 

# ... (Inside your code handling the 'onReadyForServerCompletion' callback) 

Example Code (JavaScript)

const baseUrl = "https://api.minepi.com/v2";
const serverApiKey = "your_server_api_key";

async function completePayment(paymentId, txid) {
  try {
    const response = await fetch(`${baseUrl}/payments/${paymentId}/complete`, {
      method: "POST",
      headers: {
        Authorization: `Key ${serverApiKey}`,
        "Content-Type": "application/json" 
      },
      body: JSON.stringify({ txid }) 
    });

    if (response.ok) {
      console.log("Payment successfully completed!");
    } else {
      console.error("Error completing payment:", response.status, response.statusText);
      const errorText = await response.text();
      console.error(errorText);
    }
  } catch (error) {
    console.error("Error completing payment:", error);
  }
}

// ... (Inside your code handling the 'onReadyForServerCompletion' callback)
// Assuming you receive both paymentId and txid from the callback
completePayment(paymentId, txid); 

/payments/cancel

This endpoint allows you to cancel a pending or approved Pi payment from your server.

URL: POST https://api.minepi.com/v2/payments/{payment_id}/cancel

Authorization: Server API Key (Key Authorization) See Documentation

Returns: PaymentDTO object See Documentation

Important Notes

  • Obtain payment_id: The payment_id is provided within the onReadyForServerApproval callback of the Pi App Platform SDK or when managing existing payments.
  • Reasons for Cancelling: Consider the scenarios where you might need to cancel a payment from the server-side (e.g., inventory changes, Pioneer-initiated cancellation).

Example Code (Python)

import requests

api_key = "your_server_api_key" 
header = {"Authorization": "Key " + api_key}

def cancel_payment(payment_id):
    response = requests.post(f"[invalid URL removed]", headers=header)

    if response.status_code == 200:
        print("Payment successfully cancelled!")
    else:
        print("Error cancelling payment:", response.status_code)
        print(response.text) 

# ... (Example usage within your application's logic)

Example Code (JavaScript)

const baseUrl = "https://api.minepi.com/v2";
const serverApiKey = "your_server_api_key";

async function cancelPayment(paymentId) {
  try {
    const response = await fetch(`${baseUrl}/payments/${paymentId}/cancel`, {
      method: "POST",
      headers: {
        Authorization: `Key ${serverApiKey}`,
      },
    });

    if (response.ok) {
      console.log("Payment successfully cancelled!");
    } else {
      console.error("Error cancelling payment:", response.status, response.statusText);
      const errorText = await response.text();
      console.error(errorText); 
    }
  } catch (error) {
    console.error("Error handling payment cancellation:", error);
  }
}

// ... (Example usage within your application's logic)
cancelPayment(payment_id); // Assuming you have the payment_id

/payments/incomplete_server_payments

This endpoint retrieves a list of payments that are awaiting server-side completion (i.e., awaiting the txID to be provided).

URL: GET https://api.minepi.com/v2/payments/incomplete_server_payments

Authorization: Server API Key (Key Authorization) See Documentation

Returns: An array of PaymentDTO objects See Documentation

Typical Use Cases

  • Retrieving Pending Payments: Fetch payments that require finalization from your server.
  • Error Recovery: If your application experiences an error or interruption, you can use this endpoint to resume the completion process for pending payments.

Example Code (Python)

import requests

api_key = "your_server_api_key" 
header = {"Authorization": "Key " + api_key}

response = requests.post("[https://api.minepi.com/v2/payments/incomplete_server_payments](https://api.minepi.com/v2/payments/incomplete_server_payments)", headers=header) 

if response.status_code == 200:
    incomplete_payments = response.json()
    for payment in incomplete_payments:
        # Assuming you have the txID for each payment
        complete_payment(payment['identifier'], payment_txid)  # Using your 'complete_payment' function
else:
    print("Error fetching incomplete payments:", response.status_code)
    print(response.text) 

Example Code (JavaScript)

const baseUrl = "https://api.minepi.com/v2";
const serverApiKey = "your_server_api_key";

async function fetchIncompletePayments() {
  try {
    const response = await fetch(`${baseUrl}/payments/incomplete_server_payments`, {
      method: "GET", // It's a GET request to fetch data
      headers: {
        Authorization: `Key ${serverApiKey}`,
      },
    });

    if (response.ok) {
      const incompletePayments = await response.json();
      for (const payment of incompletePayments) {
        // Assuming you have the txID for each payment (e.g., stored in a database)
        const paymentTxId = retrieveTxIdForPayment(payment.identifier); // Placeholder - replace with your logic
        completePayment(payment.identifier, paymentTxId);
      }
    } else {
      console.error("Error fetching incomplete payments:", response.status, response.statusText);
      const errorText = await response.text();
      console.error(errorText); 
    }
  } catch (error) {
    console.error("Error handling incomplete payments:", error);
  }
}

// Call the function to start the process
fetchIncompletePayments();
⚠️ **GitHub.com Fallback** ⚠️