Starship Rewards API

List Payouts API

Retrieve and filter your payout history with pagination support

List Payouts API

Retrieve a paginated list of your payouts with optional filtering by status, currency, and search terms.

Endpoint

GET /api/v1/payouts

Authentication: Bearer token required

Request Headers

Authorization: Bearer <access_token>

Query Parameters

ParameterTypeDefaultDescription
pagenumber1Page number to retrieve
limitnumber20Items per page (max: 100)
statusstring-Filter by status (e.g., completed, failed)
currencystring-Filter by currency code (e.g., USD)
searchstring-Search by reference ID or beneficiary email
sort_bystringcreated_atField to sort by
sort_orderstringDESCSort direction (ASC or DESC)

Available Status Filters

  • created - Newly created payouts
  • queued - Queued for processing
  • processing - Currently being processed
  • settling - Funds settling
  • action_required - Needs attention
  • completed - Successfully completed
  • failed - Failed payouts
  • cancelled - Cancelled payouts
  • expired - Expired payouts

Response

Success Response

Status Code: 200 OK

Response Headers:

X-Page: 1
X-Per-Page: 20
X-Total-Count: 156
X-Total-Pages: 8

Response Body:

[
  {
    "id": "pyt_xyz789abc",
    "reference_id": "PAY_2024_001",
    "status": "completed",
    "amount": 100.00,
    "currency": "USD",
    "fees": 1.50,
    "total_amount": 101.50,
    "beneficiary": {
      "email": "john.doe@example.com",
      "first_name": "John",
      "last_name": "Doe",
      "country": "US"
    },
    "description": "Bonus Payment",
    "created_at": "2024-01-15T10:30:00Z",
    "completed_at": "2024-01-15T10:35:00Z"
  },
  {
    "id": "pyt_def456ghi",
    "reference_id": "PAY_2024_002",
    "status": "processing",
    "amount": 50.00,
    "currency": "EUR",
    "fees": 0.75,
    "total_amount": 50.75,
    "beneficiary": {
      "email": "jane.smith@example.com",
      "first_name": "Jane",
      "last_name": "Smith",
      "country": "DE"
    },
    "created_at": "2024-01-15T11:00:00Z",
    "submitted_at": "2024-01-15T11:01:00Z"
  }
]

Response Fields

Payout Object

FieldTypeDescription
idstringUnique payout identifier
reference_idstringClient reference
statusstringCurrent status
amountnumberPayout amount
currencystringCurrency code
feesnumberFees charged
total_amountnumberTotal deducted (amount + fees)
beneficiaryobjectBeneficiary information
failure_codestringError code if failed (nullable)
failure_reasonstringError description if failed (nullable)
descriptionstringPayout description (nullable)
created_atstringCreation timestamp
queued_atstringQueued timestamp (nullable)
submitted_atstringSubmission timestamp (nullable)
completed_atstringCompletion timestamp (nullable)
failed_atstringFailure timestamp (nullable)
cancelled_atstringCancellation timestamp (nullable)

Pagination Headers

HeaderDescription
X-PageCurrent page number
X-Per-PageItems per page
X-Total-CountTotal number of payouts
X-Total-PagesTotal number of pages

Error Responses

401 Unauthorized

{
  "error": "UnauthorizedAccess",
  "message": "Authentication required"
}

500 Internal Server Error

{
  "error": "InternalServerError",
  "message": "Failed to retrieve payouts"
}

Examples

Basic List Request

curl -X GET "{{host}}/api/v1/payouts?page=1&limit=20" \
  -H "Authorization: Bearer your_access_token"
<?php
function listPayouts($accessToken, $params = []) {
    $defaults = ['page' => 1, 'limit' => 20];
    $params = array_merge($defaults, $params);

    $queryString = http_build_query($params);
    $url = "{{host}}/api/v1/payouts?$queryString";

    $options = [
        'http' => [
            'header' => "Authorization: Bearer $accessToken",
            'method' => 'GET'
        ]
    ];

    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);

    // Get pagination from response headers
    $headers = $http_response_header;
    $pagination = [];
    foreach ($headers as $header) {
        if (strpos($header, 'X-Total-Count:') === 0) {
            $pagination['total'] = (int) trim(substr($header, 14));
        }
        if (strpos($header, 'X-Total-Pages:') === 0) {
            $pagination['total_pages'] = (int) trim(substr($header, 14));
        }
    }

    return [
        'payouts' => json_decode($result, true),
        'pagination' => $pagination
    ];
}

// Usage
$response = listPayouts('your_access_token');

echo "Total payouts: " . $response['pagination']['total'] . "\n";

foreach ($response['payouts'] as $payout) {
    echo sprintf(
        "%s | %s | %s %s | %s\n",
        $payout['id'],
        $payout['reference_id'],
        $payout['amount'],
        $payout['currency'],
        $payout['status']
    );
}
?>

Filter by Status

# Get all completed payouts
curl -X GET "{{host}}/api/v1/payouts?status=completed&page=1&limit=50" \
  -H "Authorization: Bearer your_access_token"

# Get all failed payouts
curl -X GET "{{host}}/api/v1/payouts?status=failed" \
  -H "Authorization: Bearer your_access_token"

# Get payouts requiring action
curl -X GET "{{host}}/api/v1/payouts?status=action_required" \
  -H "Authorization: Bearer your_access_token"

Filter by Currency

# Get all USD payouts
curl -X GET "{{host}}/api/v1/payouts?currency=USD" \
  -H "Authorization: Bearer your_access_token"

# Get all EUR payouts that completed
curl -X GET "{{host}}/api/v1/payouts?currency=EUR&status=completed" \
  -H "Authorization: Bearer your_access_token"

Search Payouts

# Search by reference ID
curl -X GET "{{host}}/api/v1/payouts?search=PAY_2024" \
  -H "Authorization: Bearer your_access_token"

# Search by beneficiary email
curl -X GET "{{host}}/api/v1/payouts?search=john.doe@example.com" \
  -H "Authorization: Bearer your_access_token"

Pagination Example

async function getAllPayouts(accessToken) {
    const allPayouts = [];
    let page = 1;
    let hasMore = true;

    while (hasMore) {
        const response = await fetch(
            `/api/v1/payouts?page=${page}&limit=100`,
            {
                headers: {
                    'Authorization': `Bearer ${accessToken}`
                }
            }
        );

        const payouts = await response.json();
        allPayouts.push(...payouts);

        // Get pagination from headers
        const totalPages = parseInt(response.headers.get('X-Total-Pages'), 10);
        hasMore = page < totalPages;
        page++;
    }

    return allPayouts;
}

// Usage
const payouts = await getAllPayouts('your_access_token');
console.log(`Retrieved ${payouts.length} payouts`);

Export Payouts to CSV

async function exportPayoutsToCSV(accessToken, filters = {}) {
    // Fetch all payouts matching filters
    const queryParams = new URLSearchParams({
        limit: 100,
        ...filters
    });

    let allPayouts = [];
    let page = 1;
    let hasMore = true;

    while (hasMore) {
        const response = await fetch(
            `/api/v1/payouts?${queryParams}&page=${page}`,
            {
                headers: {
                    'Authorization': `Bearer ${accessToken}`
                }
            }
        );

        const payouts = await response.json();
        allPayouts.push(...payouts);

        // Get pagination from headers
        const totalPages = parseInt(response.headers.get('X-Total-Pages'), 10);
        hasMore = page < totalPages;
        page++;
    }

    // Generate CSV
    const headers = [
        'ID', 'Reference', 'Status', 'Amount', 'Currency',
        'Fees', 'Total', 'Beneficiary Email', 'Created At', 'Completed At'
    ];

    const rows = allPayouts.map(p => [
        p.id,
        p.reference_id,
        p.status,
        p.amount,
        p.currency,
        p.fees,
        p.total_amount,
        p.beneficiary?.email || '',
        p.created_at,
        p.completed_at || ''
    ]);

    const csv = [headers, ...rows]
        .map(row => row.map(cell => `"${cell}"`).join(','))
        .join('\n');

    return csv;
}

// Usage
const csv = await exportPayoutsToCSV('your_access_token', {
    status: 'completed',
    currency: 'USD'
});

Use Cases

Reconciliation

Regularly fetch and compare payouts for accounting reconciliation:

<?php
function reconcilePayouts($accessToken, $startDate, $endDate) {
    $payouts = [];
    $page = 1;

    do {
        $response = listPayouts($accessToken, [
            'page' => $page,
            'limit' => 100,
            'status' => 'completed'
        ]);

        foreach ($response['payouts'] as $payout) {
            $createdAt = new DateTime($payout['created_at']);

            if ($createdAt >= $startDate && $createdAt <= $endDate) {
                $payouts[] = $payout;
            }
        }

        $hasMore = $page < $response['pagination']['total_pages'];
        $page++;
    } while ($hasMore);

    // Calculate totals by currency
    $totals = [];
    foreach ($payouts as $payout) {
        $currency = $payout['currency'];
        if (!isset($totals[$currency])) {
            $totals[$currency] = ['amount' => 0, 'fees' => 0, 'count' => 0];
        }
        $totals[$currency]['amount'] += $payout['amount'];
        $totals[$currency]['fees'] += $payout['fees'];
        $totals[$currency]['count']++;
    }

    return $totals;
}
?>

Note: The listPayouts function shown earlier extracts pagination from response headers and returns both payouts and pagination.

Monitor Failed Payouts

async function monitorFailedPayouts(accessToken) {
    const response = await fetch(
        '/api/v1/payouts?status=failed&limit=50',
        {
            headers: {
                'Authorization': `Bearer ${accessToken}`
            }
        }
    );

    const payouts = await response.json();

    if (payouts.length > 0) {
        console.log(`Found ${payouts.length} failed payouts:`);

        payouts.forEach(payout => {
            console.log(`  ${payout.id}: ${payout.failure_reason}`);
        });

        // Send alert if needed
        // sendAlert(payouts);
    }

    return payouts;
}

Best Practices

  1. Use pagination - Always paginate results for large datasets
  2. Filter efficiently - Use status and currency filters to reduce data transfer
  3. Cache results - Cache payout lists for reporting dashboards
  4. Monitor regularly - Set up scheduled jobs to monitor failed/pending payouts
  5. Implement search - Use the search parameter for quick lookups