TypeScript SDK#
@hightop/sdk is the official TypeScript client for the Agent API. It ships the generated Agent API types and endpoint metadata plus a small hand-written client that handles auth, the fetch transport, idempotency enforcement, errors, timeouts, raw requests, and operation polling.
Reach for the SDK when you build agents or services in TypeScript or JavaScript and want types, autocompletion, and the lifecycle helpers handled for you. The full method-by-method SDK reference is included on this page. To compare against the CLI, MCP, and raw HTTP, see Choose Your Surface.
Install#
npm install @hightop/sdkThe SDK targets Node 20 or newer and is published to the public npm registry.
Configure a client#
Create one HightopAgentClient and reuse it. Configure exactly one auth mode — header-key or bearer token. See Authentication for how to choose.
Header-key auth:
import { HightopAgentClient } from '@hightop/sdk'
const client = new HightopAgentClient({
baseUrl: process.env.HIGHTOP_BASE_URL,
agentId: process.env.HIGHTOP_AGENT_ID,
apiKey: process.env.HIGHTOP_API_KEY,
})Bearer-token auth (for OAuth-issued tokens):
const client = new HightopAgentClient({
baseUrl: process.env.HIGHTOP_BASE_URL,
bearerToken: process.env.HIGHTOP_BEARER_TOKEN,
})baseUrl defaults to https://api.hightop.com. timeoutMs defaults to 30000. You may pass a custom fetch implementation. Auth can be omitted to call public routes, but protected endpoint calls throw until agentId/apiKey or bearerToken is set.
Quickstart#
Read the authenticated agent, then run a write through to a terminal state:
import { HightopAgentClient, createIdempotencyKey } from '@hightop/sdk'
const client = new HightopAgentClient({
baseUrl: process.env.HIGHTOP_BASE_URL,
agentId: process.env.HIGHTOP_AGENT_ID,
apiKey: process.env.HIGHTOP_API_KEY,
})
// Read
const self = await client.self.get()
console.log(self.agent.wallet_address)
// Write — supply an idempotency key for every mutation
const repay = await client.borrow.repay(
{ asset: 'GREEN', amount_usd: '10' },
{ idempotencyKey: createIdempotencyKey() },
)
// Poll the returned operation until it settles
const final = await client.operations.wait(repay.operation_id)
console.log(final.operation.status)Amounts are decimal strings, never numbers. Bare amount fields are asset-unit amounts ("1" = 1 USDC); fields named amount_usd (like the repay above) are USD-denominated. See Conventions.
Common workflows are exposed as typed domain methods (client.balances.list(), client.self.usage(), client.conversions.quote(), …); the full set is enumerated in the SDK reference below.
Every endpoint: the typed request map#
Domain helpers cover the common paths; client.request() covers every catalogued /v1/agent/* endpoint with full type inference on the request and response:
const oneOff = await client.request(
'POST /v1/agent/one-off-payments',
{ to: '0x...', asset: 'USDC', amount_usd: '25' },
{ idempotencyKey: createIdempotencyKey() },
)The generated artifact exports the supporting types:
import type {
AgentApiRequestFor,
AgentApiResponseFor,
AgentApiEndpointKey,
} from '@hightop/sdk'These are regenerated from the Agent API contract, so they always match the live surface.
Idempotency#
Every mutating endpoint requires an idempotency key. Generate one per logical operation with createIdempotencyKey(prefix?), and reuse the same key only when retrying the same logical request.
const key = createIdempotencyKey('payout')
await client.request('POST /v1/agent/one-off-payments', body, { idempotencyKey: key })
// Safe to retry with the same key + same body if the network result is unknownReusing a key with a different body returns idempotency_key_reuse_mismatch. Completed responses are stored for 24h and a retry replays the original with X-Idempotency-Replayed: true — see Conventions for the replay contract and Going to Production for retry strategy.
Operation polling#
Operation-backed (money-movement) writes return an operation id. client.operations.wait() polls until the operation reaches a terminal status or the wait times out:
try {
const result = await client.operations.wait(repay.operation_id, { timeoutMs: 60_000 })
} catch (error) {
if (error instanceof HightopAgentOperationWaitTimeoutError) {
// Still pending — the operation may yet settle; re-poll later by id
console.log(error.operation?.status)
}
}See Operations and Lifecycle for terminal statuses.
Raw requests#
rawRequest is an escape hatch for support workflows. It allows only known /v1/agent/* routes plus the OpenAPI and capabilities routes, and requires an explicit idempotencyKey for routes that need one:
const operation = await client.rawRequest({
method: 'GET',
path: '/v1/agent/operations/operation-id',
query: { include: 'onchain' },
})Errors and timeouts#
Non-2xx responses throw HightopAgentSDKError, which preserves the HTTP status, the normalized Agent API error, the original response body, response headers, and request id:
import { HightopAgentClient, HightopAgentSDKError, createIdempotencyKey } from '@hightop/sdk'
try {
await client.borrow.repay({ asset: 'GREEN', amount_usd: '10' }, { idempotencyKey: createIdempotencyKey() })
} catch (error) {
if (error instanceof HightopAgentSDKError && error.code === 'asset_not_allowed') {
console.log(error.agentError?.details)
}
}Helpers for narrowing errors without instance checks:
import { getAgentApiError, getAgentApiErrorByCode, isAgentErrorCode } from '@hightop/sdk'
const agentError = getAgentApiError(error)
if (agentError && isAgentErrorCode(agentError, 'quote_expired')) {
console.log(agentError.details.quote_id)
}
const rateLimit = getAgentApiErrorByCode(error, 'rate_limited')
if (rateLimit) {
console.log(rateLimit.details.limit_count)
}Request timeouts are synthesized client-side with code request_timeout. A timeout means the response was not received in time; if the request never reached the server it is not idempotency-cached. See Errors for the full code list.
TypeScript SDK Reference#
This page is generated from the Agent API endpoint catalog and the public @hightop/sdk client surface. Current package version: @hightop/sdk@0.1.9.
Client Construction#
The SDK exports HightopAgentClient, createIdempotencyKey, HightopAgentSDKError, HightopAgentOperationWaitTimeoutError, generated endpoint metadata, and generated request/response types.
| Config field | Purpose |
|---|---|
baseUrl | Agent API origin. Defaults to https://api.hightop.com. |
agentId + apiKey | Header-key auth. Configure both together. |
bearerToken | OAuth bearer token auth. Do not combine with header-key auth. |
fetch | Optional fetch implementation for tests or custom runtimes. |
timeoutMs | Default request timeout in milliseconds. |
Domain Helpers#
Endpoint paths are relative to /v1/agent
| Helper | Endpoint | Idempotency | Signature | Description |
|---|---|---|---|---|
client.self.get(options?) | GET/self | not required | () => Promise<AgentApiSelfResponse> | Return the authenticated agent and wallet context. |
client.self.usage(options?) | GET/self/usage | not required | () => Promise<AgentApiSelfUsageResponse> | Return current Agent API rate-limit and usage state. |
client.self.limits(options?) | GET/self/limits | not required | () => Promise<AgentApiSelfLimitsResponse> | Return effective operation permissions, spend/swap limits, and current-period usage. |
client.capabilities.get(options?) | GET/capabilities | not required | () => Promise<AgentApiCapabilitiesResponse> | Return authenticated runtime capabilities. |
client.capabilities.json(options?) | GET/capabilities.json | not required | () => Promise<AgentApiCapabilitiesResponse> | Return Agent API capabilities as JSON. |
client.openapi.get(options?) | GET/openapi.json | not required | () => Promise<Record<string, unknown>> | Fetch the public Agent API OpenAPI document. |
client.account.get(options?) | GET/account | not required | () => Promise<AgentApiAccountResponse> | Return a scoped account summary. |
client.balances.list(query?, options?) | GET/balances | not required | (query?: Record<string, unknown>) => Promise<AgentApiBalancesResponse> | List balances for the authenticated agent wallet. |
client.balances.cash(query?, options?) | GET/balances/cash | not required | (query?: Record<string, unknown>) => Promise<AgentApiBalancesResponse> | List cash balances. |
client.operations.list(query?, options?) | GET/operations | not required | (query?: AgentApiOperationsQuery) => Promise<AgentApiOperationsResponse> | List AgentOperation rows. |
client.operations.get(id, query?, options?) | GET/operations/{id} | not required | (id: string, query?: Omit<AgentApiOperationDetailQuery, "id">) => Promise<AgentApiOperationResponse> | Fetch one operation, optionally including onchain details. |
client.operations.wait(id, options?) | GET/operations/{id} | not required | (id: string, options?: WaitForOperationOptions) => Promise<AgentApiOperationResponse> | Poll an operation until a terminal status or timeout. |
client.borrow.get(options?) | GET/borrow | not required | () => Promise<AgentApiBorrowResponse> | Return borrow summary. |
client.borrow.repay(body, options) | POST/borrow/repay | required via options.idempotencyKey | (body: AgentApiBorrowRepayRequest, options: HightopAgentRequestOptions) => Promise<AgentApiWriteResponse> | Create a debt repayment operation. |
client.borrow.deleverage(body, options) | POST/borrow/deleverage | required via options.idempotencyKey | (body: AgentApiDeleverageRequest, options: HightopAgentRequestOptions) => Promise<AgentApiWriteResponse> | Create a target-LTV deleverage operation. |
client.conversions.quote(body, options) | POST/conversions/quote | required via options.idempotencyKey | (body: AgentApiConversionQuoteRequest, options: HightopAgentRequestOptions) => Promise<AgentApiConversionQuoteResponse> | Create a stateful conversion quote. |
client.conversions.execute(body, options) | POST/conversions | required via options.idempotencyKey | (body: AgentApiConversionExecuteRequest, options: HightopAgentRequestOptions) => Promise<AgentApiWriteResponse> | Execute a conversion from a quote. |
client.simulate.request(body, options?) | POST/simulate | not required | (body: AgentApiSimulateRequest) => Promise<AgentApiSimulateResponse> | Validate a write without broadcasting; policy checks run where applicable at policy depth. |
client.x402.sign(body, options) | POST/x402/sign | required via options.idempotencyKey | (body: AgentApiX402SignRequest, options: HightopAgentRequestOptions) => Promise<AgentApiX402SignResponse> | Sign a Base USDC x402 payment authorization. |
client.x402.quote(body, options?) | POST/x402/quote | not required | (body: AgentApiX402QuoteRequest) => Promise<AgentApiX402QuoteResponse> | Fetch a URL and return its supported x402 price without paying. |
client.x402.purchase(body, options) | POST/x402/purchase | required via options.idempotencyKey | (body: AgentApiX402PurchaseRequest, options: HightopAgentRequestOptions) => Promise<AgentApiX402PurchaseResponse> | Fetch a URL, satisfy an x402 challenge, and return the upstream response. |
client.request(key, payload?, options?) | multiple | depends on endpoint | <Key extends AgentApiEndpointKey>(key: Key, payload?: AgentApiRequestFor<Key>) => Promise<AgentApiResponseFor<Key>> | Typed generic access to every catalogued Agent API endpoint. |
client.rawRequest(request) | multiple | depends on endpoint | <Response = unknown>(request: HightopAgentRawRequest) => Promise<Response> | Support/debug path for known /v1/agent routes plus public OpenAPI. |
Generic Endpoint Map#
client.request(key, payload, options) covers every catalogued endpoint below. For mutating endpoints marked required, pass options.idempotencyKey; createIdempotencyKey() generates a suitable value.
| Endpoint key | Request type | Response type | Path params | Query params | Body params | Idempotency | Rate class |
|---|---|---|---|---|---|---|---|
GET /v1/agent/self | undefined | AgentApiSelfResponse | none | none | none | not required | read |
GET /v1/agent/self/usage | undefined | AgentApiSelfUsageResponse | none | none | none | not required | read |
GET /v1/agent/self/limits | undefined | AgentApiSelfLimitsResponse | none | none | none | not required | read |
GET /v1/agent/capabilities | undefined | AgentApiCapabilitiesResponse | none | none | none | not required | read |
GET /v1/agent/capabilities.json | undefined | AgentApiCapabilitiesResponse | none | none | none | not required | read |
GET /v1/agent/account | undefined | AgentApiAccountResponse | none | none | none | not required | read |
GET /v1/agent/assets | AgentApiResourceListQuery | AgentApiAssetsResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/protocols | AgentApiResourceListQuery | AgentApiProtocolsResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/balances | AgentApiResourceListQuery | AgentApiBalancesResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/balances/cash | AgentApiResourceListQuery | AgentApiBalancesResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/activity | AgentApiActivityQuery | AgentApiActivityResponse | none | cursor, limit, type, since | none | not required | read |
GET /v1/agent/operations | AgentApiOperationsQuery | AgentApiOperationsResponse | none | cursor, limit, status, type, since | none | not required | read |
GET /v1/agent/operations/{id} | AgentApiOperationDetailQuery | AgentApiOperationResponse | id | include | none | not required | read |
GET /v1/agent/recipients | AgentApiRecipientsQuery | AgentApiRecipientsResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/recipients/{id} | AgentApiRecipientDetailQuery | AgentApiRecipientResponse | id | none | none | not required | read |
POST /v1/agent/recipients/resolve | AgentApiRecipientResolveRequest | AgentApiRecipientResponse | none | none | to, asset, action | not required | read |
POST /v1/agent/payments | AgentApiPaymentCreateRequest | AgentApiWriteResponse | none | none | to, asset, deliver_as, note, slippage_percent, prefer, amount, amount_usd | required | write |
GET /v1/agent/payments | AgentApiResourceListQuery | AgentApiOperationsResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/payments/{id} | AgentApiResourceDetailQuery | AgentApiOperationResponse | id | include | none | not required | read |
POST /v1/agent/one-off-payments | AgentApiOneOffPaymentCreateRequest | AgentApiWriteResponse | none | none | to, asset, note, unlock_delay_seconds, expires_in_seconds, amount, amount_usd | required | write |
GET /v1/agent/one-off-payments | AgentApiResourceListQuery | AgentApiOperationsResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/one-off-payments/{id} | AgentApiResourceDetailQuery | AgentApiOperationResponse | id | include | none | not required | read |
POST /v1/agent/withdrawals/to-bank | AgentApiWithdrawalToBankRequest | AgentApiWriteResponse | none | none | method_id, asset, note, amount, amount_usd | required | write |
POST /v1/agent/withdrawals/to-crypto | AgentApiWithdrawalToCryptoRequest | AgentApiWriteResponse | none | none | destination_id, asset, note, amount, amount_usd | required | write |
GET /v1/agent/withdrawals | AgentApiResourceListQuery | AgentApiOperationsResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/withdrawals/{id} | AgentApiResourceDetailQuery | AgentApiOperationResponse | id | include | none | not required | read |
GET /v1/agent/withdrawal-methods | AgentApiResourceListQuery | AgentApiWithdrawalMethodsResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/deposit-methods | AgentApiResourceListQuery | AgentApiDepositMethodsResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/deposit-address | AgentApiDepositAddressQuery | AgentApiDepositAddressResponse | none | asset, chain | none | not required | read |
GET /v1/agent/earn | AgentApiResourceListQuery | AgentApiEarnResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/earn/{id} | AgentApiEarnDetailQuery | AgentApiEarnPositionResponse | id | none | none | not required | read |
GET /v1/agent/earn/opportunities | AgentApiResourceListQuery | AgentApiEarnOpportunitiesResponse | none | cursor, limit | none | not required | read |
POST /v1/agent/earn/deposit | AgentApiEarnDepositRequest | AgentApiWriteResponse | none | none | asset, vault_id, use_best_available, amount, amount_usd | required | write |
POST /v1/agent/earn/withdraw | AgentApiEarnWithdrawRequest | AgentApiWriteResponse | none | none | position_id, withdraw_all, destination_asset, allow_conversion, amount, amount_usd | required | write |
POST /v1/agent/earn/move | AgentApiEarnMoveRequest | AgentApiWriteResponse | none | none | from_position_id, move_all, to_vault_id, to_best_available, amount, amount_usd | required | write |
POST /v1/agent/earn/rewards/claim | AgentApiEarnRewardsClaimRequest | AgentApiWriteResponse | none | none | protocols | required | write |
GET /v1/agent/borrow | undefined | AgentApiBorrowResponse | none | none | none | not required | read |
POST /v1/agent/borrow | AgentApiBorrowRequest | AgentApiWriteResponse | none | none | asset, max_ltv_after, amount, amount_usd | required | write |
GET /v1/agent/borrow/collateral | AgentApiResourceListQuery | AgentApiCollateralResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/borrow/collateral-options | AgentApiResourceListQuery | AgentApiCollateralOptionsResponse | none | cursor, limit | none | not required | read |
POST /v1/agent/borrow/repay | AgentApiBorrowRepayRequest | AgentApiWriteResponse | none | none | asset, repay_all, source_asset, allow_conversion, amount, amount_usd | required | write |
POST /v1/agent/borrow/deleverage | AgentApiDeleverageRequest | AgentApiWriteResponse | none | none | target_ltv, max_repay_amount_usd, source_asset, use_available_cash_first, allow_conversion, allow_partial | required | write |
POST /v1/agent/borrow/collateral/add | AgentApiCollateralAddRequest | AgentApiWriteResponse | none | none | asset, source_asset, allow_conversion, amount, amount_usd | required | write |
POST /v1/agent/borrow/collateral/remove | AgentApiCollateralRemoveRequest | AgentApiWriteResponse | none | none | asset, remove_all, max_ltv_after, amount, amount_usd | required | write |
POST /v1/agent/conversions/quote | AgentApiConversionQuoteRequest | AgentApiConversionQuoteResponse | none | none | from_asset, to_asset, from_vault_address, to_vault_address, slippage_percent, amount, amount_usd | required | simulate |
POST /v1/agent/conversions | AgentApiConversionExecuteRequest | AgentApiWriteResponse | none | none | quote_id | required | write |
GET /v1/agent/conversions | AgentApiResourceListQuery | AgentApiOperationsResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/conversions/{id} | AgentApiResourceDetailQuery | AgentApiOperationResponse | id | include | none | not required | read |
GET /v1/agent/trusted-destinations | AgentApiResourceListQuery | AgentApiRecipientsResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/trusted-destinations/{id} | AgentApiRecipientDetailQuery | AgentApiRecipientResponse | id | none | none | not required | read |
DELETE /v1/agent/trusted-destinations/{id} | AgentApiTrustedDestinationWriteRequest | AgentApiWriteResponse | id | none | none | required | write |
POST /v1/agent/trusted-destinations/{id}/confirm | AgentApiTrustedDestinationWriteRequest | AgentApiWriteResponse | id | none | none | required | write |
POST /v1/agent/trusted-destinations/{id}/cancel | AgentApiTrustedDestinationWriteRequest | AgentApiWriteResponse | id | none | none | required | write |
GET /v1/agent/recurring-payments | AgentApiResourceListQuery | AgentApiRecipientsResponse | none | cursor, limit | none | not required | read |
GET /v1/agent/recurring-payments/{id} | AgentApiRecipientDetailQuery | AgentApiRecipientResponse | id | none | none | not required | read |
POST /v1/agent/simulate | AgentApiSimulateRequest | AgentApiSimulateResponse | none | none | method, path, body, depth | not required | simulate |
POST /v1/agent/x402/sign | AgentApiX402SignRequest | AgentApiX402SignResponse | none | none | payment_requirements, pay_to, amount, target_url, max_timeout_seconds | required | write |
POST /v1/agent/x402/quote | AgentApiX402QuoteRequest | AgentApiX402QuoteResponse | none | none | url, method, body, timeout_ms | not required | simulate |
POST /v1/agent/x402/purchase | AgentApiX402PurchaseRequest | AgentApiX402PurchaseResponse | none | none | url, method, body, max_amount | required | write |
POST /v1/agent/webhooks | AgentApiWebhookCreateRequest | AgentApiWebhookCreateResponse | none | none | url, description, event_types | required | webhook_management |
GET /v1/agent/webhooks | AgentApiResourceListQuery | AgentApiWebhooksResponse | none | cursor, limit | none | not required | webhook_management |
GET /v1/agent/webhooks/{id} | AgentApiResourceDetailQuery | AgentApiWebhookResponse | id | include | none | not required | webhook_management |
PATCH /v1/agent/webhooks/{id} | AgentApiWebhookPatchRequest | AgentApiWebhookResponse | id | none | url, description, event_types, enabled | required | webhook_management |
DELETE /v1/agent/webhooks/{id} | AgentApiWebhookDeleteRequest | AgentApiWebhookDeleteResponse | id | none | none | required | webhook_management |
POST /v1/agent/webhooks/{id}/rotate-secret | AgentApiWebhookRotateSecretRequest | AgentApiWebhookRotateSecretResponse | id | none | none | required | webhook_management |
GET /v1/agent/webhooks/{id}/deliveries | AgentApiWebhookDeliveriesQuery | AgentApiWebhookDeliveriesResponse | id | cursor, limit, status, event_id | none | not required | read |
POST /v1/agent/webhooks/{id}/test | AgentApiWebhookTestRequest | AgentApiWebhookTestResponse | id | none | none | required | webhook_management |
Next#
- Choose Your Surface — SDK vs CLI vs MCP vs raw HTTP
- Going to Production — idempotency, retries, rate limits, and error handling
- Authentication — header-key and OAuth
