# Automation Interfaces
Source: https://docs.chain.link/chainlink-automation/reference/automation-interfaces

> For the complete documentation index, see [llms.txt](/llms.txt).

Your Automation-compatible contracts may use the following interfaces. You can find them in the [Chainlink repository](https://github.com/smartcontractkit/chainlink/tree/contracts-v1.3.0/contracts/src/v0.8/automation). To understand how to implement these contracts, visit the [Compatible Contracts page](/chainlink-automation/guides/compatible-contracts).

- If you want a log event to trigger your upkeep, use the [`ILogAutomation`](#ilogautomation) interface.
- If you want to use onchain state (excluding logs) in a custom calculation to trigger your upkeep, use [`AutomationCompatibleInterface`](#automationcompatibleinterface) interface.
- If you want to call a function just based on time, consider using a [time-based upkeep](/chainlink-automation/guides/job-scheduler).
- If you want to use Automation with Data Streams, use [`StreamsLookupCompatibleInterface`](#streamslookupcompatibleinterface) interface.

## ILogAutomation

## AutomationCompatibleInterface

Custom logic upkeeps need to use the [`AutomationCompatibleInterface.sol`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/automation/interfaces/AutomationCompatibleInterface.sol) interface. Click on one of the functions below to understand its parameters and limits.

| Function Name   | Description                                                                          |
| --------------- | ------------------------------------------------------------------------------------ |
| `checkUpkeep`   | Runs offchain to determine if the `performUpkeep` function should be called onchain. |
| `performUpkeep` | Contains the logic that should be executed onchain when `checkUpkeep` returns true.  |

### checkUpkeep function

This view function contains the logic that runs offchain during every block as an [`eth_call`](https://eth.wiki/json-rpc/API#eth_call) to determine if `performUpkeep` should be executed onchain. To reduce onchain gas usage, attempt to do your gas intensive calculations offchain in `checkUpkeep` and pass the result to `performUpkeep` onchain. It is a best practice to import the [`AutomationCompatible.sol`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/automation/AutomationCompatible.sol) contract and use the `cannotExecute` modifier to ensure that the method can be used only for simulation purposes.

```solidity
function checkUpkeep(
  bytes calldata checkData
) external view override returns (bool upkeepNeeded, bytes memory performData);
```

Below are the parameters and return values of the `checkUpkeep` function. Click each value to learn more about its design patterns and best practices:

**Parameters:**

- `checkData`: Fixed and specified at upkeep registration and used in every `checkUpkeep`. Can be empty (0x).

**Return Values:**

- `upkeepNeeded`: Boolean that when True will trigger the onchain `performUpkeep` call.
- `performData`: Bytes that will be used as input parameter when calling `performUpkeep`. If you would like to encode data to decode later, try `abi.encode`.

#### checkData

You can pass information into your `checkUpkeep` function from your [upkeep registration](/chainlink-automation/guides/register-upkeep) to execute different code paths. For example, to check the balance on a specific address, set the `checkData` to abi encode the address. To learn how to create flexible upkeeps with checkData, please see our [flexible upkeeps](/chainlink-automation/guides/flexible-upkeeps) page.

```sol
function checkUpkeep(
    bytes calldata checkData
) public view returns (bool, bytes memory) {
    address wallet = abi.decode(checkData, (address));
    return (wallet.balance < 1 ether, bytes(""));
}
```

Tips on using `checkData`:

- **Managing unbounded upkeeps**: Limit the problem set of your onchain execution by creating a range bound for your upkeep to check and perform. This allows you to keep within predefined gas limits, which creates a predictable upper bound gas cost on your transactions. Break apart your problem into multiple upkeep registrations to limit the scope of work.

  **Example**: You could create an upkeep for each subset of addresses that you want to service. The ranges could be 0 to 49, 50 to 99, and 100 to 149.

- **Managing code paths**: Pass in data to your `checkUpkeep` to make your contract logic go down different code paths. This can be used in creative ways based on your use case needs.

  **Example**: You could support multiple types of upkeep within a single contract and pass a function selector through the `checkData` function.

#### performData

The response from `checkUpkeep` is passed to the `performUpkeep` function as `performData`. This allows you to perform complex and gas intensive calculations as a simulation offchain and only pass the needed data onchain.

You can create a highly flexible offchain computation infrastructure that can perform precise actions onchain by using `checkData` and `performData`. Both of these computations are entirely programmable.

### performUpkeep function for custom logic triggers

When `checkUpkeep` returns `upkeepNeeded == true`, the Automation node broadcasts a transaction to the blockchain to execute your `performUpkeep` function onchain with `performData` as an input.

Ensure that your `performUpkeep` is *idempotent*. Your `performUpkeep` function should change state such that `checkUpkeep` will not return `true` for the same subset of work once said work is complete. Otherwise the Upkeep will remain eligible and result in multiple performances by the Chainlink Automation Network on the exactly same subset of work. As a best practice, always check conditions for your upkeep at the start of your `performUpkeep` function.

```solidity
function performUpkeep(bytes calldata performData) external override;
```

**Parameters:**

- `performData`: Data which was passed back from the `checkData` simulation. If it is encoded, it can easily be decoded into other types by calling `abi.decode`. This data should always be validated against the contract's current state.

#### performData

You can perform complex and broad offchain computation, then execute onchain state changes on a subset that meets your conditions. This can be done by passing the appropriate inputs within `performData` based on the results from your `checkUpkeep`. This pattern can greatly reduce your onchain gas usage by narrowing the scope of work intelligently in your own Solidity code.

- **Identify a list of addresses that require work**: You might have a number of addresses that you are validating for conditions before your contract takes an action. Doing this onchain can be expensive. Filter the list of addresses by validating the necessary conditions within your `checkUpkeep` function. Then, pass the addresses that meet the condition through the `performData` function.
  For example, if you have a "top up" contract that ensures several hundred account balances never decrease below a threshold, pass the list of accounts that meet the conditions so that the `performUpkeep` function validates and tops up only a small subset of the accounts.
- **Identify the subset of states that must be updated**: If your contract maintains complicated objects such as arrays and structs, or stores a lot of data, you should read through your storage objects within your `checkUpkeep` and run your proprietary logic to determine if they require updates or maintenance. After that is complete, you can pass the known list of objects that require updates through the `performData` function.

## StreamsLookupCompatibleInterface