Skip to main content

Overview

The Agentic Wallet API uses a combination of HTTP status codes and structured error codes in the response envelope for comprehensive error handling.

Error Response Structure

{
  "status": "failure",
  "errorCode": "VALIDATION_ERROR",
  "failedAt": "validation",
  "stage": "validation",
  "traceId": "b2c3d4e5-f6a7-8901-bcde-f01234567891",
  "error": "Detailed error message",
  "data": null
}

Error Codes

VALIDATION_ERROR

Description: Request validation failed due to invalid parameters, missing fields, or schema violations. HTTP Status Codes: 400, 401, 403, 422 Common Causes:
  • Invalid UUID format
  • Missing required fields
  • Out of range values
  • Type mismatches
  • Invalid API key
  • Missing authentication headers
  • Insufficient scopes
Example:
curl -X POST \
  -H "x-api-key: dev-api-key" \
  -H "Content-Type: application/json" \
  -d '{"walletId": "not-a-uuid"}' \
  http://localhost:3000/api/v1/transactions
Response (400):
{
  "status": "failure",
  "errorCode": "VALIDATION_ERROR",
  "failedAt": "validation",
  "stage": "validation",
  "traceId": "...",
  "error": "Invalid walletId: expected UUID format"
}
Resolution: Fix request parameters according to the error message.

POLICY_VIOLATION

Description: The operation was denied by the policy engine. HTTP Status Codes: 403, 200 (for async transactions) Common Causes:
  • Spending limit exceeded
  • Destination not in address allowlist
  • Destination in address blocklist
  • Protocol not in allowlist
  • Token mint not allowed
  • Program ID not permitted
  • Rate limit exceeded
  • Outside allowed time window
  • Slippage exceeds maximum
  • Risk threshold exceeded
Example:
curl -X POST \
  -H "x-api-key: dev-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "walletId": "550e8400-e29b-41d4-a716-446655440000",
    "type": "transfer_sol",
    "protocol": "system-program",
    "intent": {
      "destination": "7xKLvUhXW9XqHZzN3Jw8wVHGK6R4tN2gqV9mP3kL5eXy",
      "lamports": 999999999999
    }
  }' \
  http://localhost:3000/api/v1/transactions
Response (200 - transaction created but failed policy):
{
  "status": "failure",
  "errorCode": "POLICY_VIOLATION",
  "failedAt": "policy",
  "stage": "policy_eval",
  "traceId": "...",
  "data": {
    "id": "...",
    "status": "failed",
    "policyDecision": {
      "decision": "deny",
      "reasons": ["Exceeds maxLamportsPerTx limit of 10000000"]
    }
  }
}
Resolution: Adjust the request to comply with policies or update policy rules if appropriate.

PIPELINE_ERROR

Description: Internal processing error during transaction pipeline execution. HTTP Status Codes: 500, 200 (for async transactions) Common Causes:
  • RPC connection failure
  • Transaction simulation failed
  • Signing service unavailable
  • Protocol adapter error
  • Insufficient balance
  • Invalid transaction construction
  • Network timeout
  • Service unavailable
Example:
curl -X POST \
  -H "x-api-key: dev-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "walletId": "550e8400-e29b-41d4-a716-446655440000",
    "type": "swap",
    "protocol": "jupiter",
    "intent": {
      "inputMint": "So11111111111111111111111111111111111111112",
      "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "amount": "1000000000000",
      "slippageBps": 50
    }
  }' \
  http://localhost:3000/api/v1/transactions
Response (200):
{
  "status": "failure",
  "errorCode": "PIPELINE_ERROR",
  "failedAt": "build",
  "stage": "build",
  "traceId": "...",
  "data": {
    "id": "...",
    "status": "failed",
    "error": "Insufficient balance for swap: required 1000000000000 lamports, available 1000000"
  }
}
Resolution:
  • Check service health endpoints
  • Verify wallet balance
  • Retry the operation (may be transient)
  • Check RPC endpoint status
  • Review error details in response

CONFIRMATION_FAILED

Description: Transaction was submitted to the network but confirmation failed or timed out. HTTP Status Codes: 200 (transaction exists but failed) Common Causes:
  • Confirmation timeout
  • Transaction dropped from mempool
  • Insufficient SOL for fees
  • On-chain program error
  • Network congestion
  • Blockhash expired
  • Compute budget exceeded
Example: Polling transaction status:
curl -H "x-api-key: dev-api-key" \
     http://localhost:3000/api/v1/transactions/123e4567-e89b-12d3-a456-426614174000
Response (200):
{
  "status": "failure",
  "errorCode": "CONFIRMATION_FAILED",
  "failedAt": "confirm",
  "stage": "confirm",
  "traceId": "...",
  "data": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "status": "failed",
    "signature": "5j7s...",
    "error": "Transaction confirmation timeout after 60 seconds"
  }
}
Resolution:
  • Use retry endpoint: POST /api/v1/transactions/:txId/retry
  • Check Solana network status
  • Verify transaction on-chain via signature
  • Ensure wallet has sufficient SOL for fees

HTTP Status Codes

CodeMeaningTypical Error Code
200OKN/A or async failure
201CreatedN/A
202AcceptedN/A (async processing)
400Bad RequestVALIDATION_ERROR
401UnauthorizedVALIDATION_ERROR
403ForbiddenVALIDATION_ERROR, POLICY_VIOLATION
404Not FoundVALIDATION_ERROR
422Unprocessable EntityVALIDATION_ERROR
429Too Many RequestsVALIDATION_ERROR
500Internal Server ErrorPIPELINE_ERROR
502Bad GatewayPIPELINE_ERROR
503Service UnavailablePIPELINE_ERROR

Retry Strategy

Error Codes:
  • VALIDATION_ERROR
  • POLICY_VIOLATION
Reason: These errors indicate client-side issues that won’t be resolved by retrying.Action: Fix the request or policy configuration.

Validation Error Details

Common field validation errors:

UUID Format

{
  "error": "Invalid walletId: expected UUID format"
}
Fix: Use valid UUID v4 format: 550e8400-e29b-41d4-a716-446655440000

Required Fields

{
  "error": "Missing required field: type"
}
Fix: Include all required fields in request body.

Range Validation

{
  "error": "slippageBps must be between 0 and 10000"
}
Fix: Ensure values are within allowed ranges.

Enum Values

{
  "error": "Invalid transaction type: 'send_sol'. Must be one of: transfer_sol, transfer_spl, swap, ..."
}
Fix: Use exact enum values from documentation.

Error Handling Best Practices

Log trace IDs for all errors to facilitate debugging
Parse error codes programmatically, not error messages
Implement exponential backoff for retryable errors
Monitor error rates by error code type
Handle async transaction failures by polling status

Example Error Handler

class AgenticWalletError extends Error {
  constructor(
    public readonly errorCode: string,
    public readonly failedAt: string,
    public readonly traceId: string,
    message: string
  ) {
    super(message);
    this.name = 'AgenticWalletError';
  }
}

function handleApiResponse(envelope: any) {
  if (envelope.status === 'failure') {
    throw new AgenticWalletError(
      envelope.errorCode,
      envelope.failedAt,
      envelope.traceId,
      envelope.error || envelope.errorMessage
    );
  }
  return envelope.data;
}

// Usage with retry logic
async function createTransactionWithRetry(payload: any) {
  let retries = 0;
  const maxRetries = 3;
  
  while (retries < maxRetries) {
    try {
      const response = await fetch('http://localhost:3000/api/v1/transactions', {
        method: 'POST',
        headers: {
          'x-api-key': 'dev-api-key',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(payload)
      });
      
      const envelope = await response.json();
      return handleApiResponse(envelope);
      
    } catch (error) {
      if (error instanceof AgenticWalletError) {
        // Don't retry validation or policy errors
        if (['VALIDATION_ERROR', 'POLICY_VIOLATION'].includes(error.errorCode)) {
          throw error;
        }
        
        // Retry pipeline errors
        if (error.errorCode === 'PIPELINE_ERROR' && retries < maxRetries - 1) {
          retries++;
          await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, retries)));
          continue;
        }
      }
      throw error;
    }
  }
}

Debugging Failed Requests

  1. Check the trace ID:
    grep "<traceId>" /var/log/agentic-wallet/*.log
    
  2. Query audit events:
    curl -H "x-api-key: dev-api-key" \
         "http://localhost:3000/api/v1/audit/events?txId=<txId>"
    
  3. Check service health:
    curl http://localhost:3000/health
    curl http://localhost:3006/health
    curl http://localhost:3005/health
    
  4. Review transaction replay:
    curl -H "x-api-key: dev-api-key" \
         "http://localhost:3000/api/v1/transactions/<txId>/replay"
    

Build docs developers (and LLMs) love