> ## Documentation Index
> Fetch the complete documentation index at: /docs/llms.txt
> Use this file to discover all available pages before exploring further.

# API

> The relayer, attestation, and health APIs, how to call them, and the prover service you can implement for them to call.

The IBC CLI exposes a relayer API and an attestation API, plus a shared health service.

The relayer's API has two main parts:

* `Relay` takes the transaction that sent the packets.
* `Packets` reports how far each of them got.

The attestor's API serves the attestations a light client verifies. A relayer is its usual caller, gathering proofs for a packet it is delivering. An operator calls it directly to check which attestor is answering and how far behind the head it will sign.

Both services listen on `server.listenAddr`, defaulting to `0.0.0.0:3000`.&#x20;

The `ProverService` described at the end of this page is one you implement and the relayer calls, to support a light client the CLI has no built-in prover for. The CLI does not serve it.&#x20;

To list running services:

```bash theme={null}
grpcurl -plaintext localhost:3000 list
```

```
grpc.health.v1.Health
ibc.v2.relayer.RelayerApiService
```

A process lists only the services it is running. The attestation service joins
this list when the config gives it a local attestor to serve; the relayer above
had none.&#x20;

## Health checks

Both relayers and standalone attestors expose the standard
[`grpc.health.v1.Health`](https://grpc.io/docs/guides/health-checking/) service
on their API address. `Check` is supported; `Watch` returns `UNIMPLEMENTED`.

With reflection enabled, check readiness using:

```bash theme={null}
grpcurl -plaintext -d '{"service":""}' localhost:3000 grpc.health.v1.Health/Check
```

The request's `service` field selects the check:

| Purpose | `service` | Checks |
| - | - | - |
| Readiness | `""` | Server serving and all registered services ready. The relayer pings its database with a one-second deadline; attestors have no dependency check. |
| Liveness | `grpc.health.v1.Health` | Server serving, without checking dependencies. |

## Relayer service

`ibc.v2.relayer.RelayerApiService`. `ibc relayer relay` and `ibc relayer packets` call these two.

### `Relay`

Relay tracks the packets emitted by a source transaction and submits the transactions required to complete them.

#### `RelayRequest`

| Field | Type | Description |
| - | - | - |
| `tx_hash` | `string` | The transaction that sent the packets, on the source chain. |
| `source_chain_id` | `string` | The chain that transaction was sent on. |
| `selection` | oneof: `all_packets` or `selected_packets` | Selection is required and controls only this relayer instance. |

Field names in these tables are the schema's. The JSON encoding uses lowerCamelCase, so `tx_hash` is sent as `txHash`.

`all_packets` takes every packet for which this relayer has a configured client and route. Packets without one are skipped, and the request succeeds even when that leaves nothing to relay.&#x20;

#### `SelectedPackets`

| Field | Type | Description |
| - | - | - |
| `packets` | `PacketSelector[]` | The packets to relay. At least one. |

#### `PacketSelector`

| Field | Type | Description |
| - | - | - |
| `source_client_id` | `string` | The client the packet was sent on. |
| `sequence_number` | `uint64` | The packet's number on that client. |

A `selected_packets` request fails if any packet it names is absent or has no configured route. Naming a packet that is already selected, in flight, or finished succeeds and changes nothing. &#x20;

`Relay` answers with every send packet in the transaction, including the ones it will not carry.&#x20;

#### `RelayResponse`

| Field | Type | Description |
| - | - | - |
| `packets` | `ObservedPacket[]` | Every send packet in the transaction, including those this relayer will not deliver. |

#### `ObservedPacket`

| Field | Type | Description |
| - | - | - |
| `source_client_id` | `string` | The client the packet was sent on. |
| `sequence_number` | `uint64` | The packet's number on that client. |
| `selection` | `PacketSelection` | Whether this relayer took the packet. See the values below. |

#### `PacketSelection`

| Value | Meaning |
| - | - |
| `PACKET_SELECTION_SELECTED` | Recorded for delivery by this relayer. Delivery happens afterwards and can still fail; query the packet's state to follow it. |
| `PACKET_SELECTION_NOT_SELECTED` | Configured and routed, but this request did not select it. |
| `PACKET_SELECTION_UNCONFIGURED` | No configured client or route, so this relayer skips it. |

A successful call means the relayer recorded the request. `Packets` reports what happens after that.

```bash theme={null}
grpcurl -plaintext -d '{"txHash":"0xSendTxHash","sourceChainId":"41001","allPackets":{}}' \
  localhost:3000 ibc.v2.relayer.RelayerApiService/Relay
```

### `Packets`

Packets lists the packets this relayer is aware of, most recent first.

#### `PacketsRequest`

| Field | Type | Description |
| - | - | - |
| `filter` | `PacketFilter` | Narrows the results. Every field is optional. |
| `limit` | `uint32` | Zero applies the default of 100; values above 1000 are capped. |
| `cursor` | `string` | Opaque next\_cursor from a previous response. Empty starts at the newest packet. |

#### `PacketFilter`

Every field is optional, and a request with none returns everything the relayer has recorded.

| Field | Type | Description |
| - | - | - |
| `source_chain_id` | `string` (optional) | Only packets sent from this chain. |
| `destination_chain_id` | `string` (optional) | Only packets bound for this chain. |
| `source_client_id` | `string` (optional) | Only packets sent on this client. |
| `destination_client_id` | `string` (optional) | Only packets received on this client. |
| `state` | `PacketState` (optional) | Only packets in this state. |
| `source_tx_hash` | `string` (optional) | Only packets sent by this transaction. |
| `sequence_number` | `uint64` (optional) | Only packets with this sequence number. |

#### `PacketsResponse`

| Field | Type | Description |
| - | - | - |
| `packets` | `PacketStatus[]` | One entry per matching packet on this page, newest first. |
| `has_more` | `bool` | More `packets` match beyond this page. |
| `next_cursor` | `string` | Cursor for the next page, set only when `has_more`. |

Results are paged. Ask again with `next_cursor` while `has_more` is set.

#### `PacketStatus`

| Field | Type | Description |
| - | - | - |
| `state` | `PacketState` | Where the packet got to. See the states below. |
| `sequence_number` | `uint64` | Together with `source_client_id` and `send_tx`.chain\_id, identifies the packet. |
| `source_client_id` | `string` | Together with `sequence_number` and `send_tx`.chain\_id, identifies the packet. |
| `send_tx` | `TransactionInfo` | The source-chain SendPacket transaction. Always present. |
| `recv_tx` | `TransactionInfo` | The destination-chain receive transaction, once submitted or discovered. |
| `ack_tx` | `TransactionInfo` | The source-chain acknowledgement transaction. Present for succeeded and rejected packets, and may be present while pending. |
| `timeout_tx` | `TransactionInfo` | The source-chain timeout transaction. Present for timed-out packets, and may be present while pending. |

#### `TransactionInfo`

| Field | Type | Description |
| - | - | - |
| `tx_hash` | `string` | The transaction's hash. |
| `chain_id` | `string` | The chain it was submitted to. |

#### `PacketState`

`NOT_SELECTED` and `PENDING` are still open. The other four are final. &#x20;

| Value | Meaning |
| - | - |
| `PACKET_STATE_NOT_SELECTED` | The packet was discovered but has not been selected by this relayer instance. Another relayer may still deliver it. |
| `PACKET_STATE_PENDING` | The relayer is still processing the packet. |
| `PACKET_STATE_SUCCEEDED` | The packet completed with a successful acknowledgement on the source chain. |
| `PACKET_STATE_TIMED_OUT` | The packet completed with a timeout refund on the source chain. |
| `PACKET_STATE_REJECTED` | The packet completed with an error acknowledgement on the source chain. |
| `PACKET_STATE_RELAY_FAILED` | A permanent error prevents the relayer from processing the packet. |

`REJECTED` means the packet arrived and the application refused it, which is a completed relay and a failed application call. `RELAY_FAILED` means a permanent error stopped the relayer, wherever the packet had got to.

```bash theme={null}
grpcurl -plaintext -d '{"filter":{"sourceChainId":"41001"},"limit":20}' \
  localhost:3000 ibc.v2.relayer.RelayerApiService/Packets
```

## Attestation service

`ibc.v2.attestor.AttestationService`. One process can run several attestors, so every request names one.

### `Attestation`

Both attestation calls return this shape.

| Field | Type | Description |
| - | - | - |
| `height` | `uint64` | The height of the attestation |
| `timestamp` | `uint64` (optional) | The timestamp of the block |
| `attested_data` | `bytes` | The attested data |
| `signature` | `bytes` | The attestation signature |

`attested_data` is what was signed. A light client accepts the attestation when its threshold of attestors or more sign the same data. &#x20;

### `StateAttestation`

Retrieves an attestation for a state at a given height.

#### `StateAttestationRequest`

| Field | Type | Description |
| - | - | - |
| `attestor` | `string` | Which attestor to ask, by its `name` in the `attestors` block. |
| `height` | `uint64` | The height to attest to. |

#### `StateAttestationResponse`

| Field | Type | Description |
| - | - | - |
| `attestation` | `Attestation` | The signed attestation, in the `Attestation` table. |

A height above what `LatestHeight` reports is refused, so ask for the height first.&#x20;

### `PacketAttestation`

Retrieves an attestation for a set of packets.

#### `PacketAttestationRequest`

| Field | Type | Description |
| - | - | - |
| `attestor` | `string` | Which attestor to ask, by its `name` in the `attestors` block. |
| `packets` | `bytes[]` | The packets to attest to |
| `height` | `uint64` | The height to attest to the `packets` at |
| `commitment_type` | `CommitmentType` | The type of commitment to attest (packet or acknowledgment) Defaults to COMMITMENT\_TYPE\_PACKET if not specified (for backward compatibility) |

#### `CommitmentType`

`commitment_type` selects what is being proven, which differs by direction. A delivery proves a packet commitment, an acknowledgement proves an acknowledgement commitment, and a timeout proves that no receipt exists.

| Value | Meaning |
| - | - |
| `COMMITMENT_TYPE_PACKET` | Packet commitment (for SendPacket events) |
| `COMMITMENT_TYPE_ACK` | Acknowledgment commitment (for WriteAcknowledgement events) |
| `COMMITMENT_TYPE_RECEIPT` | Receipt commitment (for Timeout events - non-membership proof) |

#### `PacketAttestationResponse`

| Field | Type | Description |
| - | - | - |
| `attestation` | `Attestation` | The signed attestation, in the `Attestation` table. |

One request carries at most 100 packets, each at most 128 KB, and a request over either limit is refused. &#x20;

### `LatestHeight`

Returns the latest height the attestor will generate attestations for.

#### `LatestHeightRequest`

| Field | Type | Description |
| - | - | - |
| `attestor` | `string` | Which attestor to ask, by its `name` in the `attestors` block. |

#### `LatestHeightResponse`

| Field | Type | Description |
| - | - | - |
| `height` | `uint64` | The highest height this attestor will attest to. |

Offset zero attests up to the chain's `finalized` tag. Above zero, the attestor reads `latest` and subtracts `finalityOffset`.&#x20;

### `Info`

Returns identity information about a configured attestor.

#### `InfoRequest`

| Field | Type | Description |
| - | - | - |
| `attestor` | `string` | Which attestor to ask, by its `name` in the `attestors` block. |

#### `InfoResponse`

| Field | Type | Description |
| - | - | - |
| `chain_id` | `string` | The chain this attestor watches. |
| `address` | `string` | The attestor's signing address. |

`address` is what a light client checks signatures against. So this call is how an operator confirms that the running attestor is the one an on-chain client expects.&#x20;

```bash theme={null}
grpcurl -plaintext -d '{"attestor":"attestor-41002"}' \
  localhost:3000 ibc.v2.attestor.AttestationService/Info
```

```json theme={null}
{
  "chainId": "41002",
  "address": "0xc7f148Da846781a9a1D9d22F699A7A88c592CCee"
}
```

## Prover service

`ibc.v2.prover.ProverService`. A relayer runs one prover per light client it
submits to. Pointing a client end at this service replaces the built-in prover
with a remote one, so a light client the CLI does not implement can be supported
by serving these three calls. Every request names the client it is scoped to, so
one service can serve many clients across many chains.

### `Client`

Every request carries one, identifying the light client the call is scoped to.

| Field | Type | Description |
| - | - | - |
| `chain_id` | `string` | The chain the light client lives on. |
| `client_id` | `string` | The light client's id on that chain. |

### `LatestProvableHeight`

LatestProvableHeight returns the highest height a subsequent ClientUpdatePayloads and PacketProofs call sharing that height can currently succeed at, with that height's counterparty-chain timestamp.

| Field | Type | Description |
| - | - | - |
| `client` | `Client` | The light client this call is scoped to. |

| Field | Type | Description |
| - | - | - |
| `height` | `uint64` | The highest counterparty height currently provable. |
| `timestamp` | `uint64` | Counterparty-chain timestamp of `height`, in seconds. |

The relayer calls this first and proves at the height it returns, so a prover
paces the relayer by holding the height back until it can prove at it.&#x20;

### `ClientUpdatePayloads`

ClientUpdatePayloads returns the encoded light-client updates that bring the client to a height.

| Field | Type | Description |
| - | - | - |
| `client` | `Client` | The light client this call is scoped to. |
| `height` | `uint64` | The counterparty height to prove at. |

| Field | Type | Description |
| - | - | - |
| `payloads` | `bytes[]` | The encoded updates, each passed unchanged as one updateMsg and submitted in order before the packets. Empty when no update is needed; each entry is a non-empty updateMsg. |

Each payload is opaque to the relayer, which passes it unchanged as `updateMsg` in one router `updateClient` call, in order, ahead of the packets in the same transaction. A prover whose client cannot reach a height in one update returns several.

### `PacketProofs`

PacketProofs proves each packet's membership or non-membership at a height, one proof per packet with indices aligned to the request.

| Field | Type | Description |
| - | - | - |
| `client` | `Client` | The light client this call is scoped to. |
| `height` | `uint64` | The counterparty height to prove at. |
| `kind` | `ProofKind` | Which commitment to prove for every packet in this request. |
| `packets` | `Packet[]` | The packets to prove, all under the same `kind` and `height`. |
| `acknowledgements` | `Acknowledgement[]` | One acknowledgement per packet, in packet order; only for acknowledgement proofs. |

| Field | Type | Description |
| - | - | - |
| `proofs` | `bytes[]` | One proof per requested packet, in request order. The proofs of one response are submitted together in one transaction, in this order, so a prover may carry material the batch shares only in the first proof. |

`proofs` is one proof per requested packet, in request order, so a response of a
different length than the request is an error.  The relayer submits all proofs of
one response in a single transaction, in that order; a prover may therefore put
material the whole batch shares (such as an account proof) only in the first proof.

| Value | Meaning |
| - | - |
| `PROOF_KIND_PACKET_COMMITMENT` | The packet was sent. Proven to receive it. |
| `PROOF_KIND_ACKNOWLEDGEMENT` | The packet was received and acknowledged. Proven to acknowledge it. |
| `PROOF_KIND_RECEIPT_ABSENCE` | The packet was never received. Proven to time it out. |

### `Packet`

The packet a proof is requested for.

| Field | Type | Description |
| - | - | - |
| `sequence` | `uint64` | The packet's sequence on the source client. |
| `source_client` | `string` | The client the packet was sent from. |
| `destination_client` | `string` | The client the packet was sent to. |
| `timeout_timestamp` | `uint64` | When the packet stops being receivable, in seconds. |
| `payloads` | `Payload[]` | The packet's application payloads. |

| Field | Type | Description |
| - | - | - |
| `source_port` | `string` | The application that sent the payload. |
| `destination_port` | `string` | The application that receives the payload. |
| `version` | `string` | The application version the payload is encoded for. |
| `encoding` | `string` | How `value` is encoded. |
| `value` | `bytes` | The application data. |

### `Acknowledgement`

The acknowledgement supplied for a packet when requesting an acknowledgement proof.

| Field | Type | Description |
| - | - | - |
| `app_acknowledgements` | `bytes[]` | The packet's encoded application acknowledgements. |

## Next steps

* [Configuration](/docs/ibc/05-ibc-cli/04-reference/01-configuration.md) for `server.listenAddr` and the `attestors` block these calls read.
* [CLI commands](/docs/ibc/05-ibc-cli/04-reference/02-cli-commands.md) for the commands that make these calls.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.