Query Intent Status
Overview
- Function: Query the current status of a payment intent
- Use Cases: Status polling, payment confirmation, monitoring payment progress
- Authentication: Optional (works with or without authentication)
JSON Schema Definition
{
"name": "query_intent_status",
"description": "Queries the current status of a payment intent. Use this to poll for status updates.",
"input_schema": {
"type": "object",
"properties": {
"intent_id": {
"type": "string",
"description": "The intent ID to query"
}
},
"required": ["intent_id"]
},
"output_schema": {
"type": "object",
"properties": {
"intent_id": {
"type": "string",
"description": "The intent ID"
},
"agent_id": {
"type": "string",
"description": "UUID of the owning agent. Present only on /v2 responses (intents created with API-key auth); absent on the public /api flow."
},
"status": {
"type": "string",
"enum": ["AWAITING_PAYMENT", "PENDING", "SOURCE_SETTLED", "TARGET_SETTLING", "TARGET_SETTLED", "VERIFICATION_FAILED", "EXPIRED", "PARTIAL_SETTLEMENT"],
"description": "Current status of the intent"
},
"target_payment": {
"type": "object",
"description": "Payment receipt on the target chain (present when status is TARGET_SETTLED)",
"properties": {
"tx_hash": {
"type": "string",
"description": "Transaction hash on the target chain"
},
"settle_proof": {
"type": "string",
"description": "Settlement proof"
},
"settled_at": {
"type": "string",
"description": "Settlement timestamp"
},
"explorer_url": {
"type": "string",
"description": "Block explorer URL on the target chain"
}
}
},
"source_payment": {
"type": "object",
"description": "Payment details on the payer (source) chain (present once the source chain has settled)"
},
"fee_breakdown": {
"type": "object",
"description": "Fee breakdown information"
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 timestamp when the intent was created"
},
"expires_at": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 timestamp when the intent expires"
}
},
"required": ["intent_id", "status"]
}
}
Parameters
Return Value
Success Response
{
"intent_id": "int_abc123xyz",
"agent_id": "8b2e9c4a-3f7a-4d1b-9e2c-5a6b7c8d9e0f",
"status": "TARGET_SETTLED",
"payer_chain": "base",
"target_chain": "ethereum",
"merchant_recipient": "0x742d35Cc...",
"target_payment": {
"tx_hash": "0x1234...abcd",
"settle_proof": "...",
"settled_at": "2024-01-01T12:05:00Z",
"explorer_url": "https://etherscan.io/tx/0x1234...abcd"
},
"source_payment": {
"chain": "base",
"tx_hash": "0x9876...fedc",
"settle_proof": "...",
"settled_at": "2024-01-01T12:04:30Z",
"explorer_url": "https://basescan.org/tx/0x9876...fedc"
},
"fee_breakdown": {
"source_chain": "base",
"source_chain_fee": "0.001",
"target_chain": "ethereum",
"target_chain_fee": "0.85",
"platform_fee": "1.00",
"platform_fee_percentage": "1.0",
"total_fee": "1.851"
},
"created_at": "2024-01-01T12:00:00Z",
"expires_at": "2024-01-01T12:10:00Z"
}
Status Values
Code Examples
TypeScript/JavaScript
import { PayClient, IntentStatus } from '@cross402/usdc';
const client = new PayClient({
baseUrl: 'https://api-pay.agent.tech',
auth: { apiKey: 'your-api-key', secretKey: 'your-secret-key' },
});
// Query intent status
const intent = await client.getIntent(intentId);
console.log(`Intent ID: ${intent.intentId}`);
console.log(`Status: ${intent.status}`);
switch (intent.status) {
case IntentStatus.TargetSettled:
console.log('Payment complete!');
console.log(`Transaction hash: ${intent.targetPayment.txHash}`);
break;
case IntentStatus.Expired:
case IntentStatus.VerificationFailed:
case IntentStatus.PartialSettlement:
console.log('Payment failed:', intent.status);
break;
default:
console.log('Payment still processing...');
// Poll again
}
Go
package main
import (
"context"
"log"
"github.com/cross402/usdc-sdk-go"
)
func main() {
client, err := pay.NewClient(
"https://api-pay.agent.tech",
pay.WithBearerAuth(apiKey, secretKey),
)
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
intent, err := client.GetIntent(ctx, intentID)
if err != nil {
log.Fatal(err)
}
log.Printf("Intent ID: %s", intent.IntentID)
log.Printf("Status: %s", intent.Status)
switch intent.Status {
case pay.StatusTargetSettled:
log.Println("Payment complete!")
log.Printf("Transaction hash: %s", intent.TargetPayment.TxHash)
case pay.StatusExpired, pay.StatusVerificationFailed, pay.StatusPartialSettlement:
log.Printf("Payment failed: %s", intent.Status)
default:
log.Println("Payment still processing...")
// Poll again
}
}
Status Lifecycle
AWAITING_PAYMENT
│
├──> EXPIRED (if not executed within 10 minutes)
│
└──> PENDING (after execution)
│
├──> VERIFICATION_FAILED (if verification fails)
│
└──> SOURCE_SETTLED
│
└──> TARGET_SETTLING
│
├──> TARGET_SETTLED (success)
│
└──> PARTIAL_SETTLEMENT (source settled, target not completed)
TARGET_SETTLING may roll back to SOURCE_SETTLED and retry; this is transparent to polling callers and only observable as a transient state dip.
Error Handling
Common Errors
For comprehensive error handling patterns and retry strategies, see Error Handling.
For polling strategies and best practices, see Payment Polling.
Important Notes
- Terminal States: Once status reaches
TARGET_SETTLED,EXPIRED,VERIFICATION_FAILED, orPARTIAL_SETTLEMENT, it will not change. Stop polling. - Polling Interval: Recommended polling interval is 2-5 seconds. Avoid polling too frequently to respect rate limits (60 req/min/IP).
- Timeout: Intents expire 10 minutes after creation. If status is still
AWAITING_PAYMENTafter expiration, it will becomeEXPIRED. - Transaction Receipt: When status is
TARGET_SETTLED, savetarget_payment.tx_hashfor record-keeping. - Rate Limiting: Be mindful of rate limits. Use exponential backoff for retries.
- v2 ownership:
GET /v2/intentsreturns the intent only if its owningagent_idmatches the API key's agent. Mismatches and intents created via the/apiflow both return404 payment intent not found. Use the same API key that created the intent, or fall back to the publicGET /api/intentsendpoint. - Optional quote fields on
getIntent:sending_amount,receiving_amount,estimated_fee, andfee_breakdownare populated by the backend after the intent leaves its initial state. Treat them as optional when polling — they are guaranteed only oncreateIntent/executeIntentresponses.
Best Practices
- Polling Strategy: Use exponential backoff to reduce API calls while maintaining responsiveness.
- Terminal State Detection: Always check for terminal states (
TARGET_SETTLED,EXPIRED,VERIFICATION_FAILED,PARTIAL_SETTLEMENT) to stop polling. - Error Handling: Implement proper error handling for network errors and API errors.
- Timeout Handling: Set a maximum polling duration to avoid infinite loops.
- User Feedback: Update UI/UX based on status changes during polling.
Related Links
- Create Intent
- Execute Intent
- Submit Proof
- Payment Polling
- Error Handling
- API Documentation: Statuses