Skip to main content

Error Codes

All Agent API errors follow a consistent JSON format. When a request fails, the response body contains success: false and an error object with a machine-readable code and a human-readable message.

Error Response Format

{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description of what went wrong."
}
}

The code field is a stable string identifier that your agent should use for programmatic error handling. The message field may change between releases and is intended for logging and debugging.

Error Code Reference

HTTP StatusCodeDescription
400VALIDATION_ERRORRequest parameters or body are invalid
401MISSING_API_KEYX-API-Key header was not provided
401INVALID_API_KEYAPI key is invalid, expired, or has been revoked
403INSUFFICIENT_SCOPEAPI key does not have the required scope for this operation
404NOT_FOUNDThe requested resource does not exist
429RATE_LIMIT_EXCEEDEDToo many requests; check the Retry-After header
500INTERNAL_ERRORAn unexpected server error occurred

Detailed Error Descriptions

MISSING_API_KEY (401)

The request did not include an X-API-Key header.

{
"success": false,
"error": {
"code": "MISSING_API_KEY",
"message": "API key is required. Include it in the X-API-Key header."
}
}

Fix: Add the X-API-Key header to your request:

curl https://home.dobprotocol.com/api/agent/pools \
-H "X-API-Key: dob_ak_your_key_here"

INVALID_API_KEY (401)

The provided API key does not match any active key in the system. This can happen if:

  • The key was typed incorrectly
  • The key has been revoked
  • The key was rotated and the old value is being used
{
"success": false,
"error": {
"code": "INVALID_API_KEY",
"message": "The provided API key is not valid or has been revoked."
}
}

Fix: Verify the key is correct. If it was revoked or rotated, create a new key or use the rotated value. See API Keys.

INSUFFICIENT_SCOPE (403)

The API key is valid but does not have the required scope for the requested operation. For example, using a read-only key to call a marketplace trade endpoint.

{
"success": false,
"error": {
"code": "INSUFFICIENT_SCOPE",
"message": "This operation requires the 'trade' scope. Your key has: ['read']."
}
}

Fix: Create a new API key with the required scopes, or use a key that already has them. See Authentication - Scopes.

OperationRequired Scope
Pool discovery, portfolio, webhooksread
Marketplace buy/list/canceltrade
Crowdfunding contributetrade

NOT_FOUND (404)

The requested resource does not exist. This can happen when:

  • A pool address is incorrect or does not exist on the specified network
  • A listing has been purchased or cancelled
  • A webhook ID is incorrect
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Pool not found: CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC on network 10."
}
}

Fix: Verify the resource identifier and network ID. Use the list endpoints to find valid identifiers.

VALIDATION_ERROR (400)

The request body or query parameters failed validation. The message field describes what is wrong, and for requests with multiple fields, an additional details array may be included.

Simple validation error:

{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Contribution amount must be greater than zero."
}
}

Multiple field validation errors:

{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed.",
"details": [
{
"field": "page",
"message": "Must be a positive integer."
},
{
"field": "limit",
"message": "Must be between 1 and 100."
}
]
}
}

Common validation errors:

ScenarioMessage
Missing required field"pool_address" is required.
Invalid network IDInvalid network_id. Supported: 1, 9, 10, 137, 8453, 42161, 84532.
Invalid sort parameterInvalid sort value. Supported: created_desc, created_asc, apr_desc, apr_asc.
Amount exceeds limitAmount exceeds remaining target (max: 17500.00).
Invalid scopesInvalid scope "write". Supported scopes: read, trade.
Max keys reachedMaximum of 10 API keys per wallet.
Expired XDRTransaction XDR has expired. Prepare a new transaction.
Pool not crowdfundingPool is not a crowdfunding campaign.
Campaign endedCrowdfunding campaign deadline has passed.

RATE_LIMIT_EXCEEDED (429)

The API key has exceeded its rate limit. The response includes a Retry-After header indicating how many seconds to wait.

{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 23 seconds."
}
}

Fix: Wait for the Retry-After duration, then retry. See Rate Limiting for implementation patterns.

INTERNAL_ERROR (500)

An unexpected error occurred on the server. This is not caused by your request and typically resolves on its own.

{
"success": false,
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred. Please try again later."
}
}

Fix: Retry the request after a short delay. If the error persists, contact DobProtocol support.

Error Handling Example

Python

import time
import requests

API_KEY = "dob_ak_your_key_here"
BASE = "https://home.dobprotocol.com/api/agent"

def api_request(method: str, path: str, max_retries: int = 3, **kwargs) -> dict:
"""Make an API request with comprehensive error handling."""
headers = {"X-API-Key": API_KEY}
if "headers" in kwargs:
headers.update(kwargs.pop("headers"))

for attempt in range(max_retries + 1):
resp = requests.request(method, f"{BASE}{path}", headers=headers, **kwargs)

if resp.status_code == 200 or resp.status_code == 201:
return resp.json()

error_body = resp.json()
error = error_body.get("error", {})
code = error.get("code", "UNKNOWN")
message = error.get("message", "Unknown error")

if code == "RATE_LIMIT_EXCEEDED":
retry_after = int(resp.headers.get("Retry-After", 60))
if attempt < max_retries:
print(f"Rate limited. Waiting {retry_after}s...")
time.sleep(retry_after)
continue

elif code == "INVALID_API_KEY":
raise PermissionError(f"API key is invalid or revoked: {message}")

elif code == "INSUFFICIENT_SCOPE":
raise PermissionError(f"Missing required scope: {message}")

elif code == "MISSING_API_KEY":
raise PermissionError("API key not configured.")

elif code == "NOT_FOUND":
return None # Resource does not exist

elif code == "VALIDATION_ERROR":
details = error.get("details", [])
if details:
field_errors = "; ".join(
f"{d['field']}: {d['message']}" for d in details
)
raise ValueError(f"Validation failed: {field_errors}")
raise ValueError(f"Validation error: {message}")

elif code == "INTERNAL_ERROR":
if attempt < max_retries:
wait = 2 ** attempt # Exponential backoff: 1, 2, 4 seconds
print(f"Server error. Retrying in {wait}s...")
time.sleep(wait)
continue

# If we get here, raise the error
raise Exception(f"API error {resp.status_code} [{code}]: {message}")

raise Exception("Max retries exceeded")


# Usage examples
try:
# Successful request
pools = api_request("GET", "/pools", params={"network_id": 10})
print(f"Found {len(pools['data'])} pools")

# 404 returns None
pool = api_request("GET", "/pools/INVALID_ADDRESS", params={"network_id": 10})
if pool is None:
print("Pool not found")

# Validation error raises ValueError
api_request("POST", "/marketplace/prepare-buy", json={"amount": -1})

except PermissionError as e:
print(f"Auth error: {e}")
except ValueError as e:
print(f"Invalid request: {e}")
except Exception as e:
print(f"Unexpected error: {e}")

curl

# Check the response and handle errors
response=$(curl -s -w "\n%{http_code}" \
-H "X-API-Key: dob_ak_your_key_here" \
"https://home.dobprotocol.com/api/agent/pools/INVALID")

http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | sed '$d')

case $http_code in
200|201)
echo "Success: $body"
;;
401)
echo "Authentication error. Check your API key."
;;
403)
echo "Permission denied. Check your key scopes."
;;
404)
echo "Resource not found."
;;
429)
echo "Rate limited. Check Retry-After header."
;;
500)
echo "Server error. Try again later."
;;
*)
echo "Unexpected status $http_code: $body"
;;
esac

HTTP Status Code Summary

StatusMeaningAgent Action
200SuccessProcess the response
201CreatedResource was created successfully
400Bad RequestFix the request parameters and retry
401UnauthorizedCheck or recreate API key
403ForbiddenUse a key with the required scope
404Not FoundVerify the resource identifier
429Too Many RequestsWait Retry-After seconds, then retry
500Server ErrorRetry with exponential backoff