> For the complete documentation index, see [llms.txt](https://otomato-2.gitbook.io/otomato-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://otomato-2.gitbook.io/otomato-docs/for-projects/otomato-sdk-integration-guide.md).

# Otomato SDK Integration Guide

The Otomato SDK lets you build automated notification directly into your frontend.

Full SDK source: [github.com/Otomatorg/otomato-sdk](https://github.com/Otomatorg/otomato-sdk)

***

### Installation

```bash
npm install otomato-sdk
```

***

### Authentication

Every API call requires an API key. To get one, email <hello@otomato.xyz>. The team will generate a key for you.

```typescript
import { apiServices } from 'otomato-sdk';

apiServices.setUrl("https://api.otomato.xyz/api");
apiServices.setAuth("your-auth-token");
```

Set these once at the top of your script. All subsequent SDK calls use them automatically.

***

### Core Concepts

| Concept      | What it is                                                             |
| ------------ | ---------------------------------------------------------------------- |
| **Trigger**  | A condition that starts a workflow (e.g. ETH price drops below $2,500) |
| **Action**   | What happens when the trigger fires (e.g. send an email)               |
| **Edge**     | The connection from a trigger to an action                             |
| **Workflow** | The container that holds triggers, actions, and edges                  |

A workflow always follows this shape:

```
Trigger → Edge → Action
```

***

### Your First Workflow: ETH Price Alert

This workflow monitors ETH price and sends an email when it drops below $2,500.

```typescript
import {
  ACTIONS, Action,
  TRIGGERS, Trigger,
  Workflow, CHAINS,
  getTokenFromSymbol, Edge,
  apiServices
} from 'otomato-sdk';

async function ethPriceAlert() {
  apiServices.setUrl("https://api.otomato.xyz/api");
  apiServices.setAuth("your-auth-token");

  // Trigger: ETH price <= $2,500 on Base
  const priceTrigger = new Trigger(TRIGGERS.TOKENS.PRICE.PRICE_MOVEMENT_AGAINST_CURRENCY);
  priceTrigger.setChainId(CHAINS.BASE);
  priceTrigger.setContractAddress(getTokenFromSymbol(CHAINS.BASE, "WETH").contractAddress);
  priceTrigger.setCondition("lte");
  priceTrigger.setComparisonValue(2500);
  priceTrigger.setParams("currency", "USD");

  // Action: Send email
  const emailAction = new Action(ACTIONS.NOTIFICATIONS.EMAIL.SEND_EMAIL);
  emailAction.setParams("to", "your-email@example.com");
  emailAction.setParams("subject", "ETH price alert");
  emailAction.setParams("body", "ETH dropped below $2,500.");

  // Wire them together
  const workflow = new Workflow(
    "ETH Price Monitor",
    [priceTrigger, emailAction],
    [new Edge({ source: priceTrigger, target: emailAction })]
  );

  await workflow.create();
  console.log("Workflow ID:", workflow.id);

  await workflow.run();
  console.log("Status:", workflow.getState());
}

ethPriceAlert();
```

> **Full example:** [simpleEthPriceMonitor.ts](https://github.com/Otomatorg/otomato-sdk/blob/master/examples/GettingStarted/simpleEthPriceMonitor.ts)

***

### DeFi Example: AAVE Health Factor Monitor

Monitor an AAVE position and get a Slack alert before liquidation risk.

```typescript
import {
  ACTIONS, Action,
  TRIGGERS, Trigger,
  Workflow, CHAINS,
  Edge, apiServices
} from 'otomato-sdk';

async function aaveHealthFactorAlert() {
  apiServices.setUrl("https://api.otomato.xyz/api");
  apiServices.setAuth(process.env.AUTH_TOKEN!);

  // Trigger: AAVE health factor drops below 1.3 on Ethereum
  const hfTrigger = new Trigger(TRIGGERS.LENDING.AAVE.HEALTH_FACTOR);
  hfTrigger.setChainId(CHAINS.ETHEREUM);
  hfTrigger.setParams("abiParams.user", "0xYourWalletAddress");
  hfTrigger.setCondition("lte");
  hfTrigger.setComparisonValue(1.3);

  // Action: Slack alert
  const slackAction = new Action(ACTIONS.NOTIFICATIONS.SLACK.SEND_MESSAGE);
  slackAction.setParams("webhook", process.env.SLACK_WEBHOOK!);
  slackAction.setParams("message", "Warning: AAVE health factor is below 1.3. Risk of liquidation.");

  const workflow = new Workflow(
    "AAVE Health Factor Monitor",
    [hfTrigger, slackAction],
    [new Edge({ source: hfTrigger, target: slackAction })]
  );

  const creation = await workflow.create();
  if (!creation.success) {
    console.error("Creation failed:", creation);
    return;
  }

  await workflow.run();
  console.log("Monitoring AAVE health factor. Workflow ID:", workflow.id);
}

aaveHealthFactorAlert();
```

> **Full example:** [aave-trigger-heath-factor.ts](https://github.com/Otomatorg/otomato-sdk/blob/master/examples/DeFi/AAVE/aave-trigger-heath-factor.ts)

***

### Using Dynamic Output in Actions

Trigger outputs can be injected into action parameters using template variables. This lets you include live on-chain values (like the current health factor) in notifications.

```typescript
// Reference the trigger's output in the email body
emailAction.setParams(
  "body",
  "Your AAVE health factor is now {{nodeMap.1.output.healthFactor}}. Take action."
);
```

The syntax is `{{nodeMap.<triggerRef>.output.<fieldName>}}`. Each node gets a ref number starting at `1`.

***

### Running via REST API (no SDK)

If you prefer raw HTTP, you can create and run workflows directly against the API.

#### Step 1: Create the workflow

```bash
curl --location 'https://api.otomato.xyz/api/workflows' \
  --header 'X-API-KEY: <YOUR_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "name": "AAVE Health Factor Alert",
    "nodes": [
      {
        "ref": "1",
        "blockId": 3,
        "type": "trigger",
        "parameters": {
          "chainId": 1,
          "abi": { "parameters": { "user": "0xYourWalletAddress" } },
          "condition": "lte",
          "comparisonValue": 1.3
        }
      },
      {
        "ref": "2",
        "blockId": 100014,
        "type": "action",
        "parameters": {
          "to": "your@email.com",
          "subject": "AAVE health factor warning",
          "body": "Health factor is {{nodeMap.1.output.healthFactor}}"
        }
      }
    ],
    "edges": [{ "source": "1", "target": "2" }]
  }'
```

Key parameters:

| Parameter         | Location                                  | Description                                                   |
| ----------------- | ----------------------------------------- | ------------------------------------------------------------- |
| `user`            | `nodes[0].parameters.abi.parameters.user` | Wallet address to monitor                                     |
| `comparisonValue` | `nodes[0].parameters.comparisonValue`     | Health factor threshold                                       |
| `to`              | `nodes[1].parameters.to`                  | Email recipient                                               |
| `body`            | `nodes[1].parameters.body`                | Use `{{nodeMap.1.output.healthFactor}}` to include live value |

Response:

```json
{
  "id": "786f0509-7eb0-4046-9c3a-1f65dee3fc99",
  "name": "AAVE Health Factor Alert",
  "state": "inactive"
}
```

Save the `id` for the next steps.

#### Step 2: Run the workflow

```bash
curl --location --request POST 'https://api.otomato.xyz/api/workflows/<WORKFLOW_ID>/run' \
  --header 'Authorization: <YOUR_API_KEY>'
```

Response:

```json
{
  "executionId": "93234c0c-b89d-4a00-8fc2-49f3a3ac8e96"
}
```

#### Step 3: Get execution history

Once a workflow has run, retrieve its past executions:

```bash
curl --location 'https://api.otomato.xyz/api/executions?wfId=<WORKFLOW_ID>' \
  --header 'Authorization: <YOUR_API_KEY>'
```

Query parameters:

| Parameter    | Required | Description                                            |
| ------------ | -------- | ------------------------------------------------------ |
| `wfId`       | Yes      | Workflow ID to query                                   |
| `limit`      | No       | Results per page                                       |
| `offset`     | No       | Results to skip (pagination)                           |
| `order`      | No       | Sort order                                             |
| `latestOnly` | No       | Set to `true` to return only the most recent execution |

Response:

```json
[
  {
    "id": "93234c0c-b89d-4a00-8fc2-49f3a3ac8e96",
    "state": "completed",
    "dateCreated": "2025-02-10T12:00:00.000Z",
    "dateModified": "2025-02-10T12:00:05.000Z"
  }
]
```

Execution states: `active`, `completed`, `failed`, `inactive`.

#### Step 4: Get full details of a single execution

```bash
curl --location 'https://api.otomato.xyz/api/executions/<EXECUTION_ID>' \
  --header 'Authorization: <YOUR_API_KEY>'
```

Response includes each node's output and timing:

```json
{
  "id": "93234c0c-b89d-4a00-8fc2-49f3a3ac8e96",
  "state": "completed",
  "workflow": {
    "nodes": [
      {
        "ref": "1",
        "state": "completed",
        "output": { "healthFactor": "2.85" },
        "timeElapsed": 1200
      },
      {
        "ref": "2",
        "state": "completed",
        "output": { "success": true },
        "timeElapsed": 800
      }
    ]
  }
}
```

***

### Important Behavior Notes

**Trigger timing:** On-chain conditions are checked every 5 minutes. Expect up to a 5-minute delay from event to notification.

**Immediate firing:** If the condition is already met when the workflow starts, the action fires immediately.

**Single execution:** Workflows execute once and stop. Contact the Otomato team if you need looping or recurring workflows.

**Chain support:** Ethereum, Base, Arbitrum, Optimism, Polygon, Avalanche, BNB Chain, and Sonic are supported. Use `CHAINS.<CHAIN_NAME>` constants.

***

### More Examples

| Protocol                     | Example                                                                                      |
| ---------------------------- | -------------------------------------------------------------------------------------------- |
| AAVE multi-chain             | [AAVE examples](https://github.com/Otomatorg/otomato-sdk/tree/master/examples/DeFi/AAVE)     |
| Morpho                       | [Morpho examples](https://github.com/Otomatorg/otomato-sdk/tree/master/examples/DeFi/Morpho) |
| Pendle                       | [Pendle examples](https://github.com/Otomatorg/otomato-sdk/tree/master/examples/DeFi/Pendle) |
| Token swaps                  | [Dex examples](https://github.com/Otomatorg/otomato-sdk/tree/master/examples/Dexes)          |
| Yield strategies             | [Yield examples](https://github.com/Otomatorg/otomato-sdk/tree/master/examples/Yield)        |
| Use cases (DCA, aggregators) | [UseCases](https://github.com/Otomatorg/otomato-sdk/tree/master/examples/UseCases)           |

Full SDK source: [github.com/Otomatorg/otomato-sdk](https://github.com/Otomatorg/otomato-sdk)

***

### Need Help?

Reach out at <hello@otomato.xyz>. The team reviews integration questions directly.
