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

# Quickstart TypeScript

> Add human approval requirements to any AI agent action in minutes

## Installation

```bash theme={null}
yarn add @humaniq/js
```

```bash theme={null}
npm install @humaniq/js
```

```bash theme={null}
bun install @humaniq/js
```

## Basic Usage

### 1. Import the SDK

```typescript theme={null}
import { needsHumanApproval } from "@humaniq/js";
```

### 2. Wrap Your Agent's Actions

<CodeGroup>
  ```typescript theme={null}
  // your tool that needs human approval. Can be anything
  const sendEmailTool = async() => {
    //...
  }
  // Wrap a function that needs approval before execution
  // defaults to an async approval request so your agent will continue after sending an approval request
  // to a human.
  const sendEmail = needsHumanApproval({actionId: "send-email"},  sendEmailTool);

  // Like normally, add your tool definitions to your LLM however you normally do, you don't need to change
  // anything there.
  // ...


  // Now jus use the wrapped tool in your tool handler for tool calling. Works with OpenAI and any other
  // Agent frameworks that support tools
  export const executeTool = async (
    toolName: string,
    toolArguments: any
  ) => {
    switch (toolName) {
      case 'sendEmail':
        // use the wrapped humaniq tool
        return sendEmail(toolArguments)
      // other tools
    }
  }


  ```
</CodeGroup>

## Add Form Fields

Present approvers with context and editable fields:

```typescript theme={null}
const processRefund = needsHumanApproval({
  type: 'sync',
  title: 'Refund Request',
  ask: (args) => `Review refund request for order ${args.orderId}`,
  approvalArguments: {
    amount: {
      type: 'number',
      value: args.amount,
      label: 'Refund Amount',
      editable: true
    },
    reason: {
      type: 'string',
      value: args.reason,
      label: 'Refund Reason',
      editable: true
    }
  }
})
```

### Auto-approve Rules

Automatically approve requests that meet certain criteria:

```typescript theme={null}
const approveAccess = needsHumanApproval({
  type: "sync",
  title: "Access Request",
  ask: (args) => `Approve access to ${args.resource}?`,
  // Auto-approve during business hours
  autoApprove: async (args) => {
    const hour = new Date().getHours();
    return hour >= 9 && hour <= 17;
  },
  // Only seek approvals for production
  shouldSeekApprovals: async (args) => {
    return args.environment === "production";
  },
});
```

### Handle Approval States

Add callbacks to handle approval states:

```typescript theme={null}
const criticalOperation = needsHumanApproval({
  type: 'sync',
  title: 'Critical Operation',
  ask: 'Approve system changes?',
  // Callback URLs for different states
  onApprovedCallbackUrl: 'https://api.your-app.com/webhooks/approved',
  onRejectedCallbackUrl: 'https://api.your-app.com/webhooks/rejected',
  onExpiredCallbackUrl: 'https://api.your-app.com/webhooks/expired'
})
```

### Multiple Approvers

Route approvals to specific team members:

```typescript theme={null}
const deployCode = needsHumanApproval({
  type: 'sync',
  title: 'Code Deployment',
  ask: 'Approve production deployment?',
  approvers: [
    { name: 'Engineering Lead', email: 'lead@company.com' },
    { name: 'DevOps Manager', email: 'devops@company.com' }
  ],
});
```

## Next Steps

<CardGroup cols={2}>
  <Card title="View Examples" icon="code" href="/recipes">
    Explore industry-specific examples and patterns
  </Card>
</CardGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Approval Request Timeouts">
    Synchronous approvals default to a 20-second timeout. Adjust this with the `syncTimeout` option:

    ```typescript theme={null}
    needsHumanApproval({
      type: 'sync',
      syncTimeout: 60000  // 60 seconds
    })
    ```
  </Accordion>

  <Accordion title="Handling Errors">
    All approval functions throw standard errors that can be caught:

    ```typescript theme={null}
    try {
      await processRefund({ amount: 100 })
    } catch (error) {
      if (error.code === 'APPROVAL_REJECTED') {
        // Handle rejection
      }
    }
    ```
  </Accordion>
</AccordionGroup>
