Subscribe to real-time funding transaction state changes (deposits, withdrawals) using gRPC streaming. This is the recommended approach for monitoring funding status.
Rate Limiting Notice The REST endpoint GET /v1/funding/transactions is rate limited. For real-time funding status updates, prefer the gRPC streaming connection to avoid rate limit issues and reduce latency.
Service Definition
Service: polymarket.v1.FundingAPI
RPC: CreateFundingTransactionSubscription
Type: Server-side streaming
service FundingAPI {
rpc CreateFundingTransactionSubscription ( CreateFundingTransactionSubscriptionRequest )
returns ( stream CreateFundingTransactionSubscriptionResponse );
}
Request Parameters
CreateFundingTransactionSubscriptionRequest
Field Type Required Description account_idslist[str]No Filter by funding account IDs. Empty = all authorized accounts. transaction_typeslist[FundingTransactionType]No Filter by transaction type. Empty = all types. resume_timeTimestampNo Resume from a previous position for reconnection.
Example Request
from polymarket.v1 import funding_pb2
# Subscribe to all funding transactions for your accounts
request = funding_pb2.CreateFundingTransactionSubscriptionRequest(
account_ids = [],
transaction_types = []
)
# Subscribe to deposits only
request = funding_pb2.CreateFundingTransactionSubscriptionRequest(
account_ids = [],
transaction_types = [funding_pb2. TRANSACTION_TYPE_DEPOSIT ]
)
# Subscribe to specific account
request = funding_pb2.CreateFundingTransactionSubscriptionRequest(
account_ids = [ "your-account-id" ],
transaction_types = []
)
Response Messages
The stream returns CreateFundingTransactionSubscriptionResponse messages when transaction states change.
Response Fields
Field Type Description changeslist[FundingTransactionChange]Transaction state changes in this batch server_timeTimestampServer timestamp (store for resume_time on reconnection)
FundingTransactionChange
Field Type Description transactionFundingTransactionThe updated transaction with current state previous_stateFundingTransactionStateThe state before this change change_timeTimestampWhen this change was detected
Transaction States
State Value Description TRANSACTION_STATE_PENDING0 Transaction initiated, awaiting processing TRANSACTION_STATE_PROCESSING9 Transaction being processed TRANSACTION_STATE_ACKNOWLEDGED1 Transaction acknowledged by payment provider TRANSACTION_STATE_COMPLETED2 Transaction successfully completed TRANSACTION_STATE_CANCELLED3 Transaction cancelled TRANSACTION_STATE_ALLOCATED4 Funds allocated TRANSACTION_STATE_REFUNDED6 Transaction fully refunded TRANSACTION_STATE_PARTIALLY_REFUNDED5 Transaction partially refunded TRANSACTION_STATE_RELEASED8 Funds released TRANSACTION_STATE_PARTIALLY_RELEASED7 Funds partially released
Common State Transitions
Deposit Flow:
PENDING β PROCESSING β ACKNOWLEDGED β COMPLETED
Deposit Failure:
PENDING β PROCESSING β CANCELLED
Withdrawal Flow:
PENDING β PROCESSING β COMPLETED
Refund Flow:
COMPLETED β PARTIALLY_REFUNDED β REFUNDED
Transaction Types
Type Value Description TRANSACTION_TYPE_DEPOSIT1 Deposit into account TRANSACTION_TYPE_WITHDRAWAL2 Withdrawal from account TRANSACTION_TYPE_TRANSFER3 Internal transfer TRANSACTION_TYPE_MANUAL_ADJUSTMENT4 Manual adjustment TRANSACTION_TYPE_SETTLEMENT_FEE5 Settlement fee TRANSACTION_TYPE_EXECUTION_FEE7 Trading execution fee
Complete Example
import grpc
from datetime import datetime
from polymarket.v1 import funding_pb2
from polymarket.v1 import funding_pb2_grpc
class FundingTransactionStreamer :
def __init__ ( self , grpc_server : str = "grpc-api.preprod.polymarketexchange.com:443" ):
self .grpc_server = grpc_server
self .access_token = None
self .last_server_time = None # For resume capability
def stream_funding_transactions ( self , account_ids : list = None ,
transaction_types : list = None ,
resume_time = None ):
"""Stream funding transaction state changes."""
if not self .access_token:
raise ValueError ( "Not authenticated. Please login first." )
# Create credentials and channel
credentials = grpc.ssl_channel_credentials()
channel = grpc.secure_channel( self .grpc_server, credentials)
stub = funding_pb2_grpc.FundingAPIStub(channel)
# Create request
request = funding_pb2.CreateFundingTransactionSubscriptionRequest(
account_ids = account_ids or [],
transaction_types = transaction_types or []
)
# Add resume_time if reconnecting
if resume_time:
request.resume_time.CopyFrom(resume_time)
# Set up metadata with authorization
metadata = [( 'authorization' , f 'Bearer { self .access_token } ' )]
try :
print ( "Starting funding transaction stream..." )
print ( f "Account filters: { account_ids or 'ALL' } " )
print ( f "Type filters: { transaction_types or 'ALL' } " )
print ( "-" * 60 )
response_stream = stub.CreateFundingTransactionSubscription(
request, metadata = metadata
)
for response in response_stream:
self ._process_response(response)
except grpc.RpcError as e:
print ( f "gRPC error: { e.code() } - { e.details() } " )
raise
except KeyboardInterrupt :
print ( " \n Stream interrupted by user" )
finally :
channel.close()
def _process_response ( self , response ):
"""Process funding transaction change response."""
# Store server_time for resume capability
if response.HasField( 'server_time' ):
self .last_server_time = response.server_time
for change in response.changes:
tx = change.transaction
print ( f " \n [ { datetime.now().strftime( '%H:%M:%S' ) } ] Transaction State Change" )
print ( f " Transaction ID: { tx.transaction_id } " )
print ( f " Type: { funding_pb2.FundingTransactionType.Name(tx.transaction_type) } " )
print ( f " Amount: { tx.amount } { tx.currency } " )
print ( f " Previous State: { funding_pb2.FundingTransactionState.Name(change.previous_state) } " )
print ( f " Current State: { funding_pb2.FundingTransactionState.Name(tx.transaction_state) } " )
print ( f " Account ID: { tx.account_id } " )
if tx.after_balance:
print ( f " New Balance: { tx.after_balance } " )
print ( "-" * 60 )
# Usage
if __name__ == "__main__" :
streamer = FundingTransactionStreamer()
# Authenticate first (see Authentication docs)
# streamer.access_token = "your_access_token"
# Stream all funding transactions
streamer.stream_funding_transactions()
# Or filter by type
streamer.stream_funding_transactions(
transaction_types = [funding_pb2. TRANSACTION_TYPE_DEPOSIT ]
)
Sample Output
Starting funding transaction stream...
Account filters: ALL
Type filters: ALL
------------------------------------------------------------
[14:30:15] Transaction State Change
Transaction ID: tx_abc123
Type: TRANSACTION_TYPE_DEPOSIT
Amount: 100.00 USD
Previous State: TRANSACTION_STATE_PENDING
Current State: TRANSACTION_STATE_PROCESSING
Account ID: acct_xyz789
------------------------------------------------------------
[14:30:45] Transaction State Change
Transaction ID: tx_abc123
Type: TRANSACTION_TYPE_DEPOSIT
Amount: 100.00 USD
Previous State: TRANSACTION_STATE_PROCESSING
Current State: TRANSACTION_STATE_COMPLETED
Account ID: acct_xyz789
New Balance: 250.00
------------------------------------------------------------
Reconnection Handling
Store the server_time from each response to enable seamless reconnection:
# On disconnect, reconnect with resume_time
if streamer.last_server_time:
streamer.stream_funding_transactions(
resume_time = streamer.last_server_time
)
The server polls for transaction changes every 15 seconds. State changes are broadcast to subscribers as they are detected.
Comparing REST vs Streaming
Aspect REST (/v1/funding/transactions) gRPC Streaming Rate Limiting Yes - subject to rate limits No - single connection Latency Poll-based, higher latency Real-time push (~15s detection) Efficiency Multiple requests needed Single persistent connection Use Case One-time queries, historical data Real-time monitoring
Recommendation: Use the gRPC streaming endpoint for monitoring deposit/withdrawal status. Reserve the REST endpoint for one-time queries or fetching historical transaction data.
Next Steps
Order Stream Stream real-time order updates
Market Data Stream Stream real-time market data
Error Handling Handle errors and reconnections
Authentication gRPC authentication setup