List Pending Transfers
List pending transfers sent by or to the member
/members/me/transfers/pendingOverview
Lists pending transfers sent by the member (direction=sent) or sent to the member's verified contacts (direction=received). Provides pagination and filtering options to manage transfer history and track gift statuses.
Authentication
Requires a valid Clerk JWT token in the Authorization header.
Query Parameters
directionquerystringFilter by direction: "sent" (transfers you sent) or "received" (transfers sent to your contacts). Default: "sent"
statusquerystringFilter by status: "PENDING", "CLAIMED", "EXPIRED", or "CANCELLED"
limitquerynumberNumber of results per page. Default: 20, Maximum: 100
offsetquerynumberPagination offset. Default: 0
Request
curl -X GET "http://localhost:3000/v1/members/me/transfers/pending?direction=sent&limit=10" \
-H "Authorization: Bearer YOUR_CLERK_JWT"Response
itemsarrayrequiredList of pending transfer objects
array items
transferIdstringrequiredUnique transfer ID
senderExternalIdstringrequiredSender's member external ID (ULID)
recipientEmailstringRecipient email address (if sent to email)
recipientPhonestringRecipient phone number (if sent to phone)
amountnumberrequiredTransfer amount in points
notestringOptional message/note from sender
statusstringrequiredTransfer status: "PENDING", "CLAIMED", "EXPIRED", or "CANCELLED"
expiresAtstringrequiredExpiration date (ISO 8601 format)
createdAtstringrequiredCreation date (ISO 8601 format)
claimedAtstringClaim date (ISO 8601 format, null if not claimed)
cancelledAtstringCancellation date (ISO 8601 format, null if not cancelled)
totalnumberrequiredTotal number of transfers matching filters
limitnumberrequiredCurrent pagination limit
offsetnumberrequiredCurrent pagination offset
Response
{
"items": [
{
"transferId": "123e4567-e89b-12d3-a456-426614174000",
"senderExternalId": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"recipientEmail": "friend@example.com",
"amount": 1000,
"note": "Happy birthday!",
"status": "PENDING",
"expiresAt": "2025-02-15T00:00:00Z",
"createdAt": "2025-01-15T10:30:00Z",
"claimedAt": null,
"cancelledAt": null
},
{
"transferId": "456e7890-e89b-12d3-a456-426614174001",
"senderExternalId": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"recipientPhone": "+1234567890",
"amount": 500,
"note": "Thanks for helping!",
"status": "CLAIMED",
"expiresAt": "2025-02-10T00:00:00Z",
"createdAt": "2025-01-10T14:20:00Z",
"claimedAt": "2025-01-12T09:15:00Z",
"cancelledAt": null
},
{
"transferId": "789e1234-e89b-12d3-a456-426614174002",
"senderExternalId": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"recipientEmail": "colleague@example.com",
"amount": 750,
"note": "Project bonus",
"status": "CANCELLED",
"expiresAt": "2025-02-20T00:00:00Z",
"createdAt": "2025-01-20T16:45:00Z",
"claimedAt": null,
"cancelledAt": "2025-01-22T11:30:00Z"
}
],
"total": 23,
"limit": 20,
"offset": 0
}Transfer Directions
Sent Transfers (direction=sent)
- Your Transfers: Transfers you created and sent to others
- Management: Can cancel pending transfers
- Tracking: Monitor claim status and expiration
- Use Case: Manage outgoing gifts and recover points
Received Transfers (direction=received)
- Incoming Gifts: Transfers sent to your verified contacts
- Claimable: Can claim pending transfers
- Visibility: See who sent you gifts
- Use Case: Claim pending points and track gift history
Transfer Statuses
PENDING
- Description: Transfer created but not yet claimed
- Actions: Can be cancelled (if sent) or claimed (if received)
- Expiration: Will expire automatically after 30 days
- Points: Held in escrow until claimed or expired
CLAIMED
- Description: Recipient has claimed the transfer
- Actions: No further actions available
- Points: Transferred to recipient's account
- Finality: Cannot be reversed or cancelled
EXPIRED
- Description: Transfer expired without being claimed
- Actions: No actions available
- Points: Automatically returned to sender
- Timeline: Expires 30 days after creation
CANCELLED
- Description: Sender cancelled the transfer
- Actions: No further actions available
- Points: Returned to sender's account
- Timeline: Can be cancelled anytime before claim/expiry
Pagination
Pagination Parameters
- limit: Results per page (1-100, default 20)
- offset: Skip number of results (default 0)
- total: Total matching transfers
- Navigation: Use offset + limit for next page
Pagination Example
const getAllTransfers = async () => {
const allTransfers = [];
let offset = 0;
const limit = 50;
while (true) {
const response = await fetch(
`/api/members/me/transfers/pending?limit=${limit}&offset=${offset}`
);
const data = await response.json();
allTransfers.push(...data.items);
if (offset + limit >= data.total) {
break; // No more pages
}
offset += limit;
}
return allTransfers;
};Use Cases
Gift Management Dashboard
const TransferDashboard = () => {
const [sentTransfers, setSentTransfers] = useState([]);
const [receivedTransfers, setReceivedTransfers] = useState([]);
useEffect(() => {
// Load sent transfers
fetch('/api/members/me/transfers/pending?direction=sent')
.then(response => response.json())
.then(data => setSentTransfers(data.items));
// Load received transfers
fetch('/api/members/me/transfers/pending?direction=received')
.then(response => response.json())
.then(data => setReceivedTransfers(data.items));
}, []);
const pendingSent = sentTransfers.filter(t => t.status === 'PENDING');
const pendingReceived = receivedTransfers.filter(t => t.status === 'PENDING');
return (
<div>
<h3>Pending Gifts Sent ({pendingSent.length})</h3>
{pendingSent.map(transfer => (
<GiftCard
key={transfer.transferId}
transfer={transfer}
actions={['cancel']}
/>
))}
<h3>Pending Gifts Received ({pendingReceived.length})</h3>
{pendingReceived.map(transfer => (
<GiftCard
key={transfer.transferId}
transfer={transfer}
actions={['claim']}
/>
))}
</div>
);
};Expiry Monitoring
const checkExpiringTransfers = async () => {
const response = await fetch('/api/members/me/transfers/pending?direction=sent&status=PENDING');
const data = await response.json();
const now = new Date();
const warning = 3 * 24 * 60 * 60 * 1000; // 3 days in ms
const expiringSoon = data.items.filter(transfer => {
const expiryDate = new Date(transfer.expiresAt);
return (expiryDate.getTime() - now.getTime()) < warning;
});
if (expiringSoon.length > 0) {
showNotification({
title: `${expiringSoon.length} gifts expiring soon`,
message: 'Consider cancelling to recover points',
actions: ['View Transfers', 'Cancel All']
});
}
return expiringSoon;
};Auto-Claim System
const autoClaimPendingGifts = async () => {
// Get all pending received transfers
const response = await fetch('/api/members/me/transfers/pending?direction=received&status=PENDING');
const data = await response.json();
let totalClaimed = 0;
const results = [];
for (const transfer of data.items) {
try {
// Attempt to claim by email or phone
const claimData = transfer.recipientEmail
? { email: transfer.recipientEmail }
: { phone: transfer.recipientPhone };
const claimResponse = await fetch('/api/members/me/transfers/claim', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(claimData)
});
const claimResult = await claimResponse.json();
totalClaimed += claimResult.totalClaimed || 0;
results.push({ transferId: transfer.transferId, success: true });
} catch (error) {
results.push({ transferId: transfer.transferId, success: false, error });
}
}
if (totalClaimed > 0) {
showNotification(`Auto-claimed ${totalClaimed} points from ${results.filter(r => r.success).length} gifts!`);
}
return { totalClaimed, results };
};Filtering and Sorting
Filter Combinations
// Get all pending transfers you sent
const pendingSent = await fetch('/api/transfers/pending?direction=sent&status=PENDING');
// Get all claimed gifts you received
const claimedReceived = await fetch('/api/transfers/pending?direction=received&status=CLAIMED');
// Get expired transfers with pagination
const expiredTransfers = await fetch('/api/transfers/pending?status=EXPIRED&limit=50&offset=100');Sorting (Client-side)
const sortTransfers = (transfers: Transfer[], sortBy: 'date' | 'amount' | 'status') => {
return [...transfers].sort((a, b) => {
switch (sortBy) {
case 'date':
return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
case 'amount':
return b.amount - a.amount;
case 'status':
return a.status.localeCompare(b.status);
default:
return 0;
}
});
};Related Endpoints
- Create Transfer - Create new pending transfers
- Claim Pending Transfer - Claim received transfers
- Cancel Pending Transfer - Cancel sent transfers
- Get Transfer Limits - Check available transfer capacity