Skip to content

Error Reference

Complete error code reference for all JarvisClaw API services. Includes HTTP status codes, x402 payment errors, and service-specific error codes.

Base URL: https://api.jarvisclaw.ai/v1

HTTP Status Codes

CodeNameDescriptionResolution
400Bad RequestMalformed request body or missing required parameters.Check request format and required fields.
401UnauthorizedInvalid or missing API key.Verify your API key is correct and active.
402Payment Requiredx402 payment needed or insufficient USDC balance.Top up USDC wallet or check payment signature.
403ForbiddenAPI key lacks permission for this resource.Check key permissions in dashboard.
404Not FoundEndpoint or resource does not exist.Verify the URL path is correct.
429Rate LimitedToo many requests in time window.Back off and retry after the Retry-After header value.
500Internal Server ErrorUnexpected server failure.Retry with exponential backoff; contact support if persistent.
502Bad GatewayUpstream provider unavailable.Retry; the provider may be temporarily down.
503Service UnavailableService overloaded or in maintenance.Wait and retry after a few seconds.

x402 Payment Errors

CodeNameDescriptionResolution
insufficient_balanceInsufficient BalanceUSDC balance too low to cover request cost.Top up your wallet with USDC (Base or Solana).
invalid_signatureInvalid SignaturePayment signature verification failed.Check private key matches the wallet with USDC.
nonce_conflictNonce ConflictPayment nonce already used (replay protection).SDK handles automatically; if manual, increment nonce.
payment_expiredPayment ExpiredPayment authorization timestamp too old.Retry the request (SDK re-signs automatically).
chain_timeoutChain TimeoutOn-chain verification timed out.Retry; blockchain may be congested.
amount_mismatchAmount MismatchSigned amount doesn't match required payment.Don't modify payment amount; let SDK calculate.
unsupported_networkUnsupported NetworkPayment chain not supported.Use Base (chain 8453) or Solana mainnet.

General API Errors

CodeNameDescriptionResolution
invalid_modelInvalid ModelRequested model not found or not available.Check /v1/models for available models.
context_too_longContext Too LongInput exceeds model's context window.Reduce message history or use a model with larger context.
content_filteredContent FilteredRequest or response blocked by safety filters.Modify the prompt to comply with usage policies.
upstream_errorUpstream ErrorThe upstream AI provider returned an error.Retry; if persistent, try a different model.

Code Examples

bash
# Check HTTP status and error body
curl -s -w "\nHTTP_STATUS:%{http_code}" \
  https://api.jarvisclaw.ai/v1/chat/completions \
  -H "Authorization: Bearer $JARVISCLAW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Hello"}]}' \
| tee >(tail -1 | grep -o "HTTP_STATUS:[0-9]*") \
| head -n -1 | jq .

# On error the body will contain:
# { "error": { "code": "invalid_model", "message": "..." } }
# or for x402:
# { "error": { "code": "insufficient_balance", "message": "..." } }
python
import jarvisclaw
from jarvisclaw.errors import (
    AuthenticationError,
    RateLimitError,
    InsufficientBalanceError,
    APIError,
    JarvisClawError,
)
import time

client = jarvisclaw.Client(api_key="your-api-key")

def chat_with_retry(messages, model="gpt-4o-mini", max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(
                model=model,
                messages=messages,
            )

        except AuthenticationError as e:
            # 401 — bad API key, no point retrying
            print(f"Authentication failed: {e.message}")
            raise

        except InsufficientBalanceError as e:
            # 402 — out of USDC; top up and retry manually
            print(f"Insufficient balance: {e.message}")
            print(f"Error code: {e.body.get('error', {}).get('code')}")
            raise

        except RateLimitError as e:
            # 429 — back off using Retry-After when available
            wait = e.retry_after or (2 ** attempt)
            print(f"Rate limited. Retrying in {wait}s …")
            time.sleep(wait)

        except APIError as e:
            # 500 / 502 / 503 — transient server errors
            if e.status_code in (500, 502, 503) and attempt < max_retries - 1:
                wait = 2 ** attempt
                print(f"Server error {e.status_code}. Retrying in {wait}s …")
                time.sleep(wait)
            else:
                # 400 / 403 / 404 or exhausted retries
                code = e.body.get("error", {}).get("code", "unknown")
                print(f"API error [{e.status_code}] {code}: {e.message}")
                raise

        except JarvisClawError as e:
            # x402 payment / SDK-level errors
            print(f"SDK error: {e}")
            raise

    raise RuntimeError("Max retries exceeded")
go
package main

import (
	"context"
	"errors"
	"fmt"
	"time"

	jarvisclaw "github.com/api-jarvisclaw/go-sdk"
)

func chatWithRetry(
	ctx context.Context,
	client *jarvisclaw.Client,
	messages []jarvisclaw.Message,
	maxRetries int,
) (*jarvisclaw.ChatCompletion, error) {
	for attempt := range maxRetries {
		resp, err := client.Chat.Completions.Create(ctx, jarvisclaw.ChatCompletionRequest{
			Model:    "gpt-4o-mini",
			Messages: messages,
		})
		if err == nil {
			return resp, nil
		}

		var authErr *jarvisclaw.AuthenticationError
		if errors.As(err, &authErr) {
			// 401 — invalid API key, no retry
			return nil, fmt.Errorf("authentication failed: %w", err)
		}

		var balanceErr *jarvisclaw.InsufficientBalanceError
		if errors.As(err, &balanceErr) {
			// 402 — top up USDC wallet
			return nil, fmt.Errorf("insufficient balance: %w", err)
		}

		var rateErr *jarvisclaw.RateLimitError
		if errors.As(err, &rateErr) {
			// 429 — back off
			wait := time.Duration(1<<attempt) * time.Second
			fmt.Printf("Rate limited. Retrying in %s ...\n", wait)
			time.Sleep(wait)
			continue
		}

		var apiErr *jarvisclaw.APIError
		if errors.As(err, &apiErr) {
			switch apiErr.StatusCode {
			case 500, 502, 503:
				// Transient server error — exponential backoff
				if attempt < maxRetries-1 {
					wait := time.Duration(1<<attempt) * time.Second
					fmt.Printf("Server error %d. Retrying in %s ...\n", apiErr.StatusCode, wait)
					time.Sleep(wait)
					continue
				}
			default:
				// 400 / 403 / 404 / upstream_error — not retryable
				code := apiErr.Body["error"]
				return nil, fmt.Errorf("api error [%d] %v: %s", apiErr.StatusCode, code, apiErr.Message)
			}
		}

		// PaymentError / other SDK errors
		return nil, fmt.Errorf("sdk error: %w", err)
	}
	return nil, fmt.Errorf("max retries (%d) exceeded", maxRetries)
}

Pay per call. No subscription. No rate limits.