Skip to content
Hightop docs header art
Hightop
API and Integrations

Errors#

Agent API errors use:

error response
application/json
{
  "ok": false,
  "error": {
    "code": "validation_failed",
    "message": "Request body is invalid.",
    "details": {}
  }
}

Always branch on error.code first. Treat details as additive context.

Stable Error Codes#

This catalog reflects Agent API contract v1.7.0. Codes marked (reserved) are part of the v1 contract but current shipped routes may not emit them yet — keep handlers for them because they may become active in a v1.x release.

HTTP statusCodes
400validation_failed, signature_expired, signature_invalid_s
401authentication_failed, agent_disabled, agent_not_yet_active, agent_expired
403owner_only_action, identity_gated_action, permission_not_granted, asset_not_allowed, recipient_not_allowed, protocol_not_allowed, limit_exceeded, ltv_too_high, insufficient_scope, operation_feature_disabled, cooldown_active (reserved)
404not_found, cheque_not_found
409quote_expired, quote_already_consumed, idempotency_key_reuse_mismatch, idempotency_request_in_progress, operation_not_cancellable, operation_not_supported_for_wrapper_version, ltv_target_unreachable, signature_invalid_nonce, time_delay_not_reached, cheque_replaced, loot_not_available, starter_agent_not_removable, owner_changed_pending_state, one_off_payment_already_paid, one_off_payment_not_active, one_off_payment_replaced, one_off_payment_stale, pending_one_off_payment_settings_exists, pending_one_off_payment_settings_missing, pending_time_lock_exists, migration_blocked_pending_one_off_payment_settings, migration_blocked_pending_time_lock, timelock_not_elapsed (reserved), rule_changed_during_execution (reserved)
422insufficient_funds, slippage_exceeded, price_stale, invalid_pull_one_off_payment_flags
429rate_limited
500internal_error
502execution_failed, execution_timeout, batch_step_failed (reserved)
503agent_api_cutover_in_progress, agent_api_chain_unavailable

The 503 codes are transient: back off and retry. See Going to Production.

Note: invalid_token below is an OAuth Bearer challenge code (RFC 6750), surfaced via the WWW-Authenticate header — it is not an Agent API error.code value.

Authentication Details#

authentication_failed covers missing credentials, unknown agent ids, key mismatches, missing owners, and soft-deleted owners.

These codes are returned only after the supplied key matches the agent:

  • agent_disabled
  • agent_not_yet_active
  • agent_expired

OAuth Challenges#

OAuth Bearer auth adds RFC 6750 challenge headers.

Malformed, expired, revoked, wrong-audience, or otherwise invalid tokens return 401 invalid_token.

text
example
WWW-Authenticate: Bearer resource_metadata="https://api.hightop.com/.well-known/oauth-protected-resource/v1/agent", error="invalid_token"

Valid tokens that lack a required route scope return 403 insufficient_scope.

text
example
WWW-Authenticate: Bearer resource_metadata="https://api.hightop.com/.well-known/oauth-protected-resource/v1/agent", error="insufficient_scope", scope="agent:withdrawals:write"

The error body also uses insufficient_scope.

Typed error.details#

Some errors include stable details shapes.

CodeDetails
idempotency_request_in_progressidempotency_key: string
idempotency_key_reuse_mismatchidempotency_key: string, original_method: string, original_path: string
slippage_exceededquote_id: string, expected_out: string, min_amount_out: string
quote_already_consumedquote_id: string, consumed_at: string | null, optional consumed_by_operation_id: string
quote_expiredquote_id: string, expired_at: string
rate_limitedlimit_count: number, attempted_count: number, period: "transaction"
limit_exceededcap: number, observed: number, period: "rolling_30d" | "active" or max_endpoints: number
ltv_too_highcurrent_ltv: string, estimated_ltv_after: string, max_ltv_after: string
ltv_target_unreachablecurrent_ltv: string, target_ltv: string, max_repay_usd: string, required_repay_usd: string, estimated_ltv_after: string

Example:

error response
application/json
{
  "ok": false,
  "error": {
    "code": "quote_expired",
    "message": "Quote has expired.",
    "details": {
      "quote_id": "00000000-0000-0000-0000-000000000000",
      "expired_at": "2026-05-16T18:30:00.000Z"
    }
  }
}

Previous

Operations and Lifecycle

Next

Webhooks