API Reference - alxspiker/Pi-Developer-Handbook GitHub Wiki

Pi Network API Reference

Table of Contents

Making API Calls

This document outlines how to make authorized API calls to the Pi Network servers.

Authorization

All API requests require either an Access Token (Bearer Token) or a Server API Key for authentication.

  • Access Token (Bearer Token): Used for endpoints that require user-specific data.
  • Server API Key: Used for endpoints with app-level data.

/me

This endpoint provides verified Pioneer information associated with the provided Access Token.

URL: GET https://api.minepi.com/v2/me

Authorization: Access Token (Bearer Token) See Access Token Documentation

Returns: UserDTO object See UserDTO Documentation

Purpose

  • Retrieve Pioneer UID: Obtain the app-specific unique identifier for the authenticated Pioneer.
  • Get Pioneer Username: Access the Pioneer's Pi Network username (if the username scope was granted during authentication).

Example Code (Python)

import requests

access_token = "accessToken_Obtained_from_App_Frontend"  # Replace with your token
header = {"Authorization": "Bearer " + access_token}
response = requests.get("[https://api.minepi.com/v2/me](https://api.minepi.com/v2/me)", headers=header)

if response.status_code == 200:
    userDTO = response.json()
    print("Success!")
    print("Pioneer UID:", userDTO['uid'])
    print("Pioneer Username:", userDTO['username'])  # If 'username' scope was granted
else:
    print("Error:", response.status_code)
    print(response.text) 

Example Code: (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();