Skip to main content
Version: 1.14.0

Class: CCIPAPIClient

Defined in: api/index.ts:143

Client for interacting with the CCIP REST API.

Can be used standalone or injected into Chain classes.

Examples​

Standalone usage

TypeScript
const api = CCIPAPIClient.fromUrl()
const latency = await api.getLaneLatency(sourceSelector, destSelector)
console.log(`Latency: ${latency.totalMs}ms`)

With custom options

TypeScript
const api = CCIPAPIClient.fromUrl('https://custom.api.url', {
logger: myLogger,
fetch: myCustomFetch,
})

Error handling

TypeScript
try {
const latency = await api.getLaneLatency(sourceSelector, destSelector)
} catch (err) {
if (err instanceof CCIPHttpError) {
console.error(`API error ${err.context.status}: ${err.context.apiErrorMessage}`)
if (err.isTransient) {
// Retry after delay
}
}
}

Constructors​

Constructor​

new CCIPAPIClient(baseUrl?: string, ctx?: CCIPAPIClientContext): CCIPAPIClient

Defined in: api/index.ts:165

Creates a new CCIPAPIClient instance.

Parameters​

ParameterTypeDescription
baseUrl?stringBase URL for the CCIP API (defaults to DEFAULT_API_BASE_URL)
ctx?CCIPAPIClientContextOptional context with logger and custom fetch

Returns​

CCIPAPIClient

Properties​

baseUrl​

readonly baseUrl: string

Defined in: api/index.ts:145

Base URL for API requests


logger​

readonly logger: Logger

Defined in: api/index.ts:147

Logger instance


timeoutMs​

readonly timeoutMs: number

Defined in: api/index.ts:149

Request timeout in milliseconds

Methods​

getEncodedMessage()​

getEncodedMessage(messageId: string, options?: { signal?: AbortSignal; }): Promise<{ encodedMessage: string; offRamp: string; }>

Defined in: api/index.ts:897

Fetches a CCIP v2.0 message's encoded form and destination OffRamp: the part of its execution input that doesn't depend on verification progress. Unlike getExecutionInput, it doesn't fail while CCV verifications are still missing, so a caller can collect those itself (e.g. Chain.getVerifications with verifiers).

Parameters​

ParameterTypeDescription
messageIdstringThe CCIP message ID (32-byte hex string)
options?{ signal?: AbortSignal; }Optional request options. - signal — an AbortSignal to cancel the request.
options.signal?AbortSignal-

Returns​

Promise<{ encodedMessage: string; offRamp: string; }>

The 0x-prefixed MessageV1Codec-encoded message and the OffRamp address

Throws​

CCIPMessageIdNotFoundError when message not found (404)

Throws​

CCIPVersionUnsupportedError if the message predates CCIP v2.0

Throws​

CCIPHttpError on other HTTP errors


getExecutionInput()​

getExecutionInput(messageId: string, options?: { signal?: AbortSignal; }): Promise<ExecutionInput & Lane<CCIPVersion> & { offRamp: string; }>

Defined in: api/index.ts:815

Fetches the execution input for a given message by id. For v2.0 messages, returns { encodedMessage, verifications }. For pre-v2 messages, returns { message, offchainTokenData, proofs, ... } with merkle proof.

Parameters​

ParameterTypeDescription
messageIdstringThe CCIP message ID (32-byte hex string)
options?{ signal?: AbortSignal; }Optional request options. - signal — an AbortSignal to cancel the request.
options.signal?AbortSignal-

Returns​

Promise<ExecutionInput & Lane<CCIPVersion> & { offRamp: string; }>

Execution input with offRamp address and lane info

Throws​

CCIPMessageIdNotFoundError when message not found (404)

Throws​

CCIPTimeoutError if request times out

Throws​

CCIPAbortError if request is aborted via signal

Throws​

CCIPHttpError on other HTTP errors

Example​

TypeScript
const api = CCIPAPIClient.fromUrl()
const execInput = await api.getExecutionInput('0x1234...')
// Use with dest.execute():
const { offRamp, ...input } = execInput
await dest.execute({ offRamp, input, wallet })

getLaneLatency()​

getLaneLatency(sourceChainSelector: bigint, destChainSelector: bigint, numberOfBlocks?: number, options?: { signal?: AbortSignal; sourceTokenAddress?: string; }): Promise<LaneLatencyResponse>

Defined in: api/index.ts:299

Fetches estimated lane latency between source and destination chains.

Parameters​

ParameterTypeDescription
sourceChainSelectorbigintSource chain selector (bigint)
destChainSelectorbigintDestination chain selector (bigint)
numberOfBlocks?numberOptional number of block confirmations for latency calculation. When omitted or 0, uses the lane's default finality. When provided as a positive integer, the API returns latency for that custom finality value (sent as numOfBlocks query parameter).
options?{ signal?: AbortSignal; sourceTokenAddress?: string; }Optional request options. - sourceTokenAddress — token-specific latency profile instead of the lane-wide estimate. Most lanes have none and throw CCIPLaneLatencyInsufficientDataError. - signal — an AbortSignal to cancel the request.
options.signal?AbortSignal-
options.sourceTokenAddress?string-

Returns​

Promise<LaneLatencyResponse>

Promise resolving to LaneLatencyResponse with totalMs

Throws​

CCIPLaneNotFoundError when lane not found (404)

Throws​

CCIPLaneLatencyInsufficientDataError when the API has too little history for the requested profile (400 INSUFFICIENT_DATA)

Throws​

CCIPTimeoutError if request times out

Throws​

CCIPAbortError if request is aborted via signal

Throws​

CCIPHttpError on other HTTP errors with context:

  • status - HTTP status code (e.g., 500)
  • statusText - HTTP status message
  • apiErrorCode - API error code (e.g., "INVALID_PARAMETERS")
  • apiErrorMessage - Human-readable error message from API

Examples​

Basic usage

TypeScript
const latency = await api.getLaneLatency(
5009297550715157269n, // Ethereum mainnet
4949039107694359620n, // Arbitrum mainnet
)
console.log(`Estimated delivery: ${Math.round(latency.totalMs / 60000)} minutes`)

Custom block confirmations

TypeScript
const latency = await api.getLaneLatency(
5009297550715157269n, // Ethereum mainnet
4949039107694359620n, // Arbitrum mainnet
10, // 10 block confirmations
)

Token-specific latency, falling back to the lane-wide estimate

TypeScript
let latency
try {
latency = await api.getLaneLatency(src, dest, undefined, { sourceTokenAddress: token })
} catch (err) {
if (!(err instanceof CCIPLaneLatencyInsufficientDataError)) throw err
latency = await api.getLaneLatency(src, dest)
}

Handling specific API errors

TypeScript
try {
const latency = await api.getLaneLatency(sourceSelector, destSelector)
} catch (err) {
if (err instanceof CCIPHttpError && err.context.apiErrorCode === 'LANE_NOT_FOUND') {
console.error('This lane does not exist')
}
}

getMessageById()​

getMessageById(messageId: string, options?: { signal?: AbortSignal; }): Promise<{ lane: Lane<CCIPVersion>; log: { blockTimestamp: number; data: Record<string, unknown> | BytesLike; tx?: { blockNumber: number; error?: unknown; from: string; hash: string; logs?: readonly { blockTimestamp: number; data: Record<string, unknown> | BytesLike; tx?: { hash: string; blockNumber: number; timestamp: number; from: string; error?: unknown; logs?: readonly { transactionHash: string; blockNumber: number; address: string; topics: readonly string[]; index: number; blockTimestamp: number; data: Record<...> | BytesLike; tx?: ... | undefined; }[] | undefined; } | undefined; }[]; timestamp: number; }; }; message: { ccipReceiveGasLimit: number; ccvAndExecutorHash: string; data: string; destBlob: string; destChainSelector: bigint; encodedMessage: string; executionGasLimit: number; feeToken: string; feeTokenAmount: bigint; finality: FinalityRequested; messageId: string; messageNumber: bigint; offRampAddress: string; onRampAddress: string; receipts: readonly { destBytesOverhead: bigint; destGasLimit: bigint; extraArgs: string; feeTokenAmount: bigint; issuer: string; }[]; receiver: string; sender: string; sequenceNumber: bigint; sourceChainSelector: bigint; tokenAmountBeforeTokenPoolFees: bigint; tokenAmounts: readonly TokenTransferV1[]; verifierBlobs: readonly string[]; } | { data: string; feeToken: string; feeTokenAmount: bigint; gasLimit: bigint; messageId: string; nonce: bigint; receiver: string; sender: string; sequenceNumber: bigint; sourceChainSelector: bigint; sourceTokenData: readonly string[]; strict: boolean; tokenAmounts: readonly { amount: bigint; token: string; }[]; } | CCIPMessage_V1_5_EVM | CCIPMessage_V1_6_EVM | CCIPMessage_V1_6_Solana | CCIPMessage_V1_6_Sui; metadata: APICCIPRequestMetadata; tx: Omit<ChainTransaction, "logs">; }>

Defined in: api/index.ts:411

Fetches a CCIP message by its unique message ID.

Parameters​

ParameterTypeDescription
messageIdstringThe message ID (0x prefix + 64 hex characters, e.g., "0x1234...abcd")
options?{ signal?: AbortSignal; }Optional request options. - signal — an AbortSignal to cancel the request.
options.signal?AbortSignal-

Returns​

Promise<{ lane: Lane<CCIPVersion>; log: { blockTimestamp: number; data: Record<string, unknown> | BytesLike; tx?: { blockNumber: number; error?: unknown; from: string; hash: string; logs?: readonly { blockTimestamp: number; data: Record<string, unknown> | BytesLike; tx?: { hash: string; blockNumber: number; timestamp: number; from: string; error?: unknown; logs?: readonly { transactionHash: string; blockNumber: number; address: string; topics: readonly string[]; index: number; blockTimestamp: number; data: Record<...> | BytesLike; tx?: ... | undefined; }[] | undefined; } | undefined; }[]; timestamp: number; }; }; message: { ccipReceiveGasLimit: number; ccvAndExecutorHash: string; data: string; destBlob: string; destChainSelector: bigint; encodedMessage: string; executionGasLimit: number; feeToken: string; feeTokenAmount: bigint; finality: FinalityRequested; messageId: string; messageNumber: bigint; offRampAddress: string; onRampAddress: string; receipts: readonly { destBytesOverhead: bigint; destGasLimit: bigint; extraArgs: string; feeTokenAmount: bigint; issuer: string; }[]; receiver: string; sender: string; sequenceNumber: bigint; sourceChainSelector: bigint; tokenAmountBeforeTokenPoolFees: bigint; tokenAmounts: readonly TokenTransferV1[]; verifierBlobs: readonly string[]; } | { data: string; feeToken: string; feeTokenAmount: bigint; gasLimit: bigint; messageId: string; nonce: bigint; receiver: string; sender: string; sequenceNumber: bigint; sourceChainSelector: bigint; sourceTokenData: readonly string[]; strict: boolean; tokenAmounts: readonly { amount: bigint; token: string; }[]; } | CCIPMessage_V1_5_EVM | CCIPMessage_V1_6_EVM | CCIPMessage_V1_6_Solana | CCIPMessage_V1_6_Sui; metadata: APICCIPRequestMetadata; tx: Omit<ChainTransaction, "logs">; }>

Promise resolving to APICCIPRequest with message details

Throws​

CCIPMessageIdNotFoundError when message not found (404)

Throws​

CCIPTimeoutError if request times out

Throws​

CCIPAbortError if request is aborted via signal

Throws​

CCIPHttpError on HTTP errors with context:

  • status - HTTP status code
  • statusText - HTTP status message
  • apiErrorCode - API error code (e.g., "INVALID_MESSAGE_ID")
  • apiErrorMessage - Human-readable error message

Examples​

Basic usage

TypeScript
const request = await api.getMessageById(
'0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
)
console.log(`Status: ${request.metadata.status}`)
console.log(`From: ${request.message?.sender}`)

Handling not found

TypeScript
try {
const request = await api.getMessageById(messageId)
} catch (err) {
if (err instanceof CCIPMessageIdNotFoundError) {
console.error('Message not found, it may still be in transit')
}
}

getMessageIdsInTx()​

getMessageIdsInTx(txHash: string, options?: { signal?: AbortSignal; }): Promise<string[]>

Defined in: api/index.ts:774

Fetches message IDs from a source transaction hash.

Parameters​

ParameterTypeDescription
txHashstringSource transaction hash.
options?{ signal?: AbortSignal; }Optional request options. - signal — an AbortSignal to cancel the request.
options.signal?AbortSignal-

Returns​

Promise<string[]>

Promise resolving to array of message IDs.

Remarks​

Uses CCIPAPIClient.searchMessages internally with sourceTransactionHash filter and limit: 100.

Throws​

CCIPMessageNotFoundInTxError when no messages found (404 or empty).

Throws​

CCIPUnexpectedPaginationError when hasNextPage is true.

Throws​

CCIPTimeoutError if request times out.

Throws​

CCIPAbortError if request is aborted via signal.

Throws​

CCIPHttpError on HTTP errors.

Examples​

Basic usage

TypeScript
const messageIds = await api.getMessageIdsInTx(
'0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
)
console.log(`Found ${messageIds.length} messages`)

Fetch full details for each message

TypeScript
const api = CCIPAPIClient.fromUrl()
const messageIds = await api.getMessageIdsInTx(txHash)
for (const id of messageIds) {
const request = await api.getMessageById(id)
console.log(`${id}: ${request.metadata.status}`)
}

getVerifications()​

getVerifications(messageId: string, options?: { signal?: AbortSignal; }): Promise<VerifierResult[]>

Defined in: api/index.ts:470

Fetches CCV verification results for a CCIP v2.0 message from the API.

Validates that all requiredCCVs addresses have a matching verification in the response. Throws CCIPMessageNotVerifiedYetError if the verifiers field is absent or any required CCV is missing.

Parameters​

ParameterTypeDescription
messageIdstringThe CCIP message ID
options?{ signal?: AbortSignal; }Optional request options (signal for cancellation)
options.signal?AbortSignal-

Returns​

Promise<VerifierResult[]>

CCIPVerifications with policy and verifier results

Throws​

CCIPMessageNotVerifiedYetError if verifications are not yet available


searchAllMessages()​

searchAllMessages(filters?: MessageSearchFilters, options?: { cursor?: string; limit?: number; signal?: AbortSignal; }): AsyncGenerator<MessageSearchResult>

Defined in: api/index.ts:723

Async generator that streams all messages matching the given filters, handling cursor-based pagination automatically.

Parameters​

ParameterTypeDescription
filters?MessageSearchFiltersOptional search filters (same as CCIPAPIClient.searchMessages).
options?{ cursor?: string; limit?: number; signal?: AbortSignal; }Optional request options: - limit — per-page fetch size (number of results fetched per API call). The total number of results is controlled by the consumer — break out of the loop to stop early. - cursor — resume from a cursor returned by an earlier CCIPAPIClient.searchMessages call instead of starting at the first page. The cursor already encodes the filters it was issued for; filters may repeat them or be omitted, but must not contradict them (the API answers 400 INVALID_PARAMETER_COMBINATION if they differ). - signal — an AbortSignal that, when aborted, cancels the next page fetch.
options.cursor?string-
options.limit?number-
options.signal?AbortSignal-

Returns​

AsyncGenerator<MessageSearchResult>

AsyncGenerator yielding MessageSearchResult one at a time, across all pages.

Throws​

CCIPTimeoutError if a page request times out.

Throws​

CCIPAbortError if a page request is aborted via signal.

Throws​

CCIPHttpError on HTTP errors (4xx/5xx, except 404 which yields nothing).

See​

Examples​

Iterate all messages for a sender

TypeScript
for await (const msg of api.searchAllMessages({ sender: '0x...' })) {
console.log(`${msg.messageId}: ${msg.status}`)
}

Stop after collecting 5 results

TypeScript
const results: MessageSearchResult[] = []
for await (const msg of api.searchAllMessages({ sender: '0x...' })) {
results.push(msg)
if (results.length >= 5) break
}

searchMessages()​

searchMessages(filters?: MessageSearchFilters, options?: { cursor?: string; limit?: number; signal?: AbortSignal; }): Promise<MessageSearchPage>

Defined in: api/index.ts:611

Searches CCIP messages using filters with cursor-based pagination.

Parameters​

ParameterTypeDescription
filters?MessageSearchFiltersOptional search filters. Ignored when options.cursor is provided (the cursor already encodes the original filters).
options?{ cursor?: string; limit?: number; signal?: AbortSignal; }Optional pagination and request options: - limit — max results per page. - cursor — opaque token from a previous MessageSearchPage for the next page. - signal — an AbortSignal to cancel the request.
options.cursor?string-
options.limit?number-
options.signal?AbortSignal-

Returns​

Promise<MessageSearchPage>

Promise resolving to a MessageSearchPage with results and pagination info.

Remarks​

A 404 response is treated as "no results found" and returns an empty page, unlike CCIPAPIClient.getMessageById which throws on 404. When paginating with a cursor, the filters parameter is ignored because the cursor encodes the original filters.

Throws​

CCIPTimeoutError if request times out.

Throws​

CCIPAbortError if request is aborted via signal.

Throws​

CCIPHttpError on HTTP errors (4xx/5xx, except 404 which returns empty).

See​

Examples​

Search by sender

TypeScript
const page = await api.searchMessages({
sender: '0x9d087fC03ae39b088326b67fA3C788236645b717',
})
for (const msg of page.data) {
console.log(`${msg.messageId}: ${msg.status}`)
}

Paginate through all results

TypeScript
let page = await api.searchMessages({ sender: '0x...' }, { limit: 10 })
const all = [...page.data]
while (page.hasNextPage) {
page = await api.searchMessages(undefined, { cursor: page.cursor! })
all.push(...page.data)
}

Search by token pool address

TypeScript
// No named filter for pool address; `q` covers it.
const pool = '0x20B79D39Bd44dEee4F89B1e9d0e3b945fde06491'
const page = await api.searchMessages({ q: pool })
// `q` spans several fields, so check the one you meant:
for (const msg of page.data) {
const detail = await api.getMessageById(msg.messageId)
if (detail.message.tokenAmounts.some((t) => t.sourcePoolAddress === pool)) {
console.log(msg.messageId)
}
}

Filter by lane and sender

TypeScript
const page = await api.searchMessages({
sender: '0x9d087fC03ae39b088326b67fA3C788236645b717',
sourceChainSelector: 16015286601757825753n,
destChainSelector: 14767482510784806043n,
})

fromUrl()​

static fromUrl(baseUrl?: string, ctx?: CCIPAPIClientContext): CCIPAPIClient

Defined in: api/index.ts:203

Factory method for creating memoized CCIPAPIClient. Should be preferred over constructor, to avoid multiple fetch/retry/rate-limits instances, unless that's specifically required.

Parameters​

ParameterTypeDescription
baseUrl?stringBase URL for the CCIP API
ctx?CCIPAPIClientContextOptional context

Returns​

CCIPAPIClient

New CCIPAPIClient instance