> 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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://otomato-2.gitbook.io/otomato-docs/for-projects/otomato-sdk-integration-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
