npm package: @honecrm/sdk
Description: Official TypeScript SDK for Hone CRM
Latest version: 0.1.1

# @honecrm/sdk

Official TypeScript SDK for [Hone CRM](https://honecrm.com).

## Install

```bash
npm install @honecrm/sdk
```

## Quick start

```typescript
import { HoneCRM } from '@honecrm/sdk';

const client = new HoneCRM({
  apiKey: 'your-api-key',
});

// List deals
const { deals } = await client.deals.list({ stage: 'qualified' });

// Create a deal
const deal = await client.deals.create({
  name: 'Acme renewal',
  contact: { name: 'Jane Doe', email: 'jane@acme.com' },
  value: 50_000,
});
```

## Configuration

```typescript
const client = new HoneCRM({
  apiKey: 'hone_...', // Required
  baseUrl: 'https://api.honecrm.com/v1', // Default
  timeout: 30_000, // Default (ms)
});
```

## Resources

All resources follow a consistent CRUD pattern: `list()`, `get(id)`, `create(input)`, `update(id, input)`, `delete(id)`.

### Deals

```typescript
const { deals, totalCount } = await client.deals.list({
  stage: 'negotiation',
  minValue: 10_000,
  limit: 25,
});

const deal = await client.deals.get('deal-id');

const newDeal = await client.deals.create({
  name: 'Enterprise contract',
  contact: { name: 'John Smith', email: 'john@corp.com', company: 'Corp Inc' },
  value: 120_000,
  stage: 'proposal',
  tags: ['enterprise', 'q2'],
});

await client.deals.update('deal-id', { stage: 'closed_won' });
await client.deals.delete('deal-id');
```

### Contacts

```typescript
const { contacts } = await client.contacts.list({ search: 'jane' });
const contact = await client.contacts.create({
  name: 'Jane Doe',
  email: 'jane@acme.com',
  companyName: 'Acme Corp',
});
```

### Companies

```typescript
const { companies } = await client.companies.list({ industry: 'SaaS' });
const company = await client.companies.create({
  name: 'Acme Corp',
  domain: 'acme.com',
  industry: 'SaaS',
});
```

### Notes

```typescript
const { notes } = await client.notes.list({ entityType: 'deal', entityId: 'deal-id' });
await client.notes.create({
  entityType: 'deal',
  entityId: 'deal-id',
  content: 'Follow-up call went well.',
});
```

### Reminders

```typescript
const { reminders } = await client.reminders.list({ status: 'pending' });
await client.reminders.create({
  entityType: 'deal',
  entityId: 'deal-id',
  title: 'Send proposal',
  dueAt: '2026-03-15T09:00:00Z',
});
```

### Workflows

```typescript
const { workflows } = await client.workflows.list();

const workflow = await client.workflows.create({
  name: 'Auto-assign high-value deals',
  trigger: { type: 'event', eventType: 'deal.created' },
  steps: [
    {
      id: 'check-value',
      name: 'Check deal value',
      type: 'condition',
      condition: {
        field: 'trigger.data.deal.value',
        operator: 'gte',
        value: 100_000,
        trueBranch: 'assign-senior',
      },
    },
    {
      id: 'assign-senior',
      name: 'Assign to senior rep',
      type: 'action',
      action: {
        type: 'assign_deal',
        params: {
          dealId: '{{trigger.data.deal.id}}',
          assigneeId: 'senior-rep-user-id',
        },
      },
    },
  ],
});

// Manually trigger a workflow
const run = await client.workflows.trigger('workflow-id', { dealId: 'deal-123' });

// Check run status
const { runs } = await client.workflows.listRuns('workflow-id');
const runDetails = await client.workflows.getRun('workflow-id', run.id);
```

### Webhooks

```typescript
await client.webhooks.create({
  url: 'https://your-app.com/webhooks',
  events: ['deal.created', 'deal.updated'],
});
```

### Search

```typescript
const results = await client.search.query('acme');
const similar = await client.search.similar({ text: 'enterprise SaaS deal' });
```

### API Keys

```typescript
const { apiKeys } = await client.apiKeys.list();
const { apiKey, rawKey } = await client.apiKeys.create({
  name: 'CI integration',
  scopes: ['deals:read', 'deals:write'],
});
```

### Agents

```typescript
const agent = await client.agents.create({
  name: 'Deal Enrichment Bot',
  apiKeyId: 'key-id',
  scopes: ['deals:read', 'deals:write', 'companies:read'],
});
```

## Pagination

All list endpoints support cursor-based pagination:

```typescript
let nextToken: string | undefined;

do {
  const response = await client.deals.list({ limit: 50, nextToken });
  // process response.deals
  nextToken = response.nextToken;
} while (nextToken);
```

## Error handling

```typescript
import { HoneCRM, HoneCRMError } from '@honecrm/sdk';

try {
  await client.deals.get('nonexistent-id');
} catch (err) {
  if (err instanceof HoneCRMError) {
    console.error(err.message);    // "Deal not found"
    console.error(err.code);       // "NOT_FOUND"
    console.error(err.statusCode); // 404
    console.error(err.requestId);  // "req_abc123"
  }
}
```

## Rate limiting

Rate limit info is available after each request:

```typescript
await client.deals.list();
console.log(client.rateLimit);
// { limit: 100, remaining: 99, reset: 1710000000 }
```

## Abort requests

```typescript
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);

const deals = await client.deals.list({}, { signal: controller.signal });
```

## Requirements

- Node.js >= 18 (uses native `fetch`)
- TypeScript >= 5.0 (optional, for type support)

## License

MIT