Understanding the asynchronous job pattern for Bankr API operations.
Source: Agent API Reference
The CLI handles submit-poll-complete automatically. For installation and login, see the main SKILL.md.
bankr prompt "What is my ETH balance?" # submit + poll + display
bankr status <jobId> # check a specific job
bankr cancel <jobId> # cancel a running jobCall the endpoints below with curl, fetch, or any HTTP client. All requests require an X-API-Key header.
All operations follow this pattern:
1. SUBMIT → Send prompt, get job ID
2. POLL → Check status every 2s
3. COMPLETE → Process results
Submit a natural language prompt to start a job.
CLI equivalent: bankr prompt "What is my ETH balance?"
Request:
curl -X POST "https://api.bankr.bot/agent/prompt" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "What is my ETH balance?"}'Continue a conversation:
curl -X POST "https://api.bankr.bot/agent/prompt" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "And what about SOL?", "threadId": "thr_ABC123"}'Request Body:
- prompt (string, required): The prompt to send to the AI agent (max 10,000 characters)
- threadId (string, optional): Continue an existing conversation thread. If omitted, a new thread is created.
Response (202 Accepted):
{
"success": true,
"jobId": "job_abc123",
"threadId": "thr_XYZ789",
"status": "pending",
"message": "Job submitted successfully"
}Error Responses:
| Status | Error | Cause |
|---|---|---|
| 400 | Invalid request or Prompt too long |
Bad input or exceeds 10,000 chars |
| 401 | Authentication required |
Missing or invalid API key |
| 403 | Agent API access not enabled |
API key lacks agent access |
Check job status and results.
CLI equivalent: bankr status job_abc123
Request:
curl -X GET "https://api.bankr.bot/agent/job/job_abc123" \
-H "X-API-Key: YOUR_API_KEY"Response (200 OK):
{
"success": true,
"jobId": "job_abc123",
"threadId": "thr_XYZ789",
"status": "completed",
"prompt": "What is my ETH balance?",
"response": "You have 0.5 ETH worth approximately $1,825.",
"richData": [],
"statusUpdates": [
{"message": "Checking balances...", "timestamp": "2025-01-26T10:00:00Z"},
{"message": "Calculating USD values...", "timestamp": "2025-01-26T10:00:02Z"}
],
"createdAt": "2025-01-26T10:00:00Z",
"completedAt": "2025-01-26T10:00:03Z",
"processingTime": 3000
}Error Responses:
| Status | Error | Cause |
|---|---|---|
| 400 | Job ID required |
Missing job ID in path |
| 401 | Authentication required |
Missing or invalid API key |
| 404 | Job not found |
Job ID doesn't exist or doesn't belong to you |
Cancel a pending or processing job. Cancel requests are idempotent — cancelling an already-cancelled job returns success.
CLI equivalent: bankr cancel job_abc123
Request:
curl -X POST "https://api.bankr.bot/agent/job/job_abc123/cancel" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json"Response (200 OK):
{
"success": true,
"jobId": "job_abc123",
"status": "cancelled",
"prompt": "Swap 0.1 ETH for USDC",
"createdAt": "2025-01-26T10:00:00Z",
"cancelledAt": "2025-01-26T10:00:05Z"
}Error Responses:
| Status | Error | Cause |
|---|---|---|
| 400 | Job ID required, Job already completed, or Job already failed |
Invalid state for cancellation |
| 401 | Authentication required |
Missing or invalid API key |
| 404 | Job not found |
Job ID doesn't exist or doesn't belong to you |
| Status | Description | Action |
|---|---|---|
pending |
Job queued, not yet started | Keep polling |
processing |
Job is being processed | Keep polling, show updates |
completed |
Job finished successfully | Read response and richData |
failed |
Job encountered an error | Check error field |
cancelled |
Job was cancelled | No further action |
- success: Boolean, true if request succeeded
- jobId: Unique job identifier
- threadId: Conversation thread ID (reuse to continue the conversation)
- status: Current job status (
pending,processing,completed,failed,cancelled) - prompt: Original user prompt
- createdAt: ISO 8601 timestamp
- response: Natural language response text
- richData: Array of structured data objects (see Rich Data below)
- completedAt: When job finished (ISO 8601)
- processingTime: Duration in milliseconds
- statusUpdates: Array of progress messages (
{message, timestamp}) - startedAt: When processing began (ISO 8601)
- cancellable: Boolean, whether the job can still be cancelled
- error: Error message
- completedAt: When failure occurred (ISO 8601)
- cancelledAt: When the job was cancelled (ISO 8601)
Completed jobs may include a richData array containing structured data (e.g., token info, price quotes, charts). Each entry has:
type RichData = {
type?: string; // e.g., "token_info", "price_quote"
[key: string]: unknown; // Additional structured data
};The exact shape depends on the operation performed. The response field always contains a human-readable text summary regardless of what richData contains.
- Interval: 2 seconds between requests
- Typical duration: 30 seconds to 2 minutes
- Maximum: 5 minutes (then suggest cancellation)
#!/bin/bash
JOB_ID="job_abc123"
MAX_ATTEMPTS=150 # 5 minutes
for i in $(seq 1 $MAX_ATTEMPTS); do
sleep 2
STATUS=$(curl -s "https://api.bankr.bot/agent/job/$JOB_ID" \
-H "X-API-Key: $API_KEY" | jq -r '.status')
case "$STATUS" in
completed|failed|cancelled)
break
;;
*)
echo "Polling... ($i/$MAX_ATTEMPTS)"
;;
esac
doneTrack what you've shown:
LAST_UPDATE_COUNT=0
while true; do
RESULT=$(get_job_status "$JOB_ID")
CURRENT_COUNT=$(echo "$RESULT" | jq '.statusUpdates | length')
if [ "$CURRENT_COUNT" -gt "$LAST_UPDATE_COUNT" ]; then
# Show new updates only
echo "$RESULT" | jq -r ".statusUpdates[$LAST_UPDATE_COUNT:] | .[].message"
LAST_UPDATE_COUNT=$CURRENT_COUNT
fi
STATUS=$(echo "$RESULT" | jq -r '.status')
[ "$STATUS" != "pending" ] && [ "$STATUS" != "processing" ] && break
sleep 2
donePrice queries:
- Clear, direct answer
- Include symbol and price
- Example: "ETH is currently $3,245.67"
Trading confirmations:
- Confirm amounts
- Show transaction hash
- Mention gas costs if significant
Portfolio display:
- List token amounts and USD values
- Group by chain if multi-chain
- Show total portfolio value
Market analysis:
- Summarize key insights
- Highlight important data points
- Keep concise
Errors:
- Explain what went wrong clearly
- Suggest next steps
- Avoid technical jargon
{
"error": "Authentication required",
"message": "API key is missing or invalid"
}Resolution: Check API key, ensure "Agent API" access is enabled at https://bankr.bot/api
{
"error": "Agent API access not enabled",
"message": "Enable agent access for your API key"
}Resolution: Visit https://bankr.bot/api and enable Agent API access on your key
{
"error": "Rate limit exceeded",
"message": "Retry after 60 seconds"
}Resolution: Wait and retry, implement exponential backoff
{
"success": true,
"status": "failed",
"error": "Insufficient balance for trade"
}Resolution: Check specific error, guide user to fix
- Validate input before submitting
- Handle errors gracefully
- Store job ID for tracking
- Show confirmation to user
- Use 2-second interval - Don't poll too fast
- Show progress - Display status updates
- Set timeout - Don't poll forever
- Handle network errors - Retry with backoff
- Parse response carefully
- Check richData for structured results
- Format output nicely
- Save to history for reference
- Identify error type quickly
- Provide clear explanation to user
- Suggest fixes when possible
- Retry intelligently
1. Submit: "What is my ETH balance?"
2. Poll every 2s (completes in ~5s)
3. Show: "You have 0.5 ETH ($1,825)"
1. Submit: "Swap 0.1 ETH for USDC"
2. Poll every 2s
- Update: "Checking balance..."
- Update: "Finding best route..."
- Update: "Executing swap..."
3. Complete after ~45s
4. Show: "Swapped 0.1 ETH for 365 USDC"
5. Display transaction hash
1. Submit: "Analyze ETH price"
2. Poll every 2s
- Update: "Fetching price data..."
- Update: "Running technical analysis..."
- Update: "Analyzing sentiment..."
3. Complete after ~30s
4. Show formatted analysis with key metrics
- Never expose in client code
- Use environment variables or config.json
- Rotate periodically
- Monitor usage
- Revoke immediately if leaked at https://bankr.bot/api
- Validate user input
- Sanitize prompts
- Check amounts/addresses
- Confirm before critical operations
- Don't leak sensitive info
- Be helpful but not revealing
- Log internally, show safely
- Guide users constructively
Remember: The asynchronous pattern allows Bankr to handle complex operations that may take time, while keeping you informed of progress.