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

# SDK reference

> @versoai/core: two functions and the webhook event types.

```bash theme={null}
npm install @versoai/core
```

Requirements: Node.js 20 or newer. The package is ESM only (`import`); from CommonJS use `await import("@versoai/core")`. Source: [github.com/vrsoai/verso-fetch](https://github.com/vrsoai/verso-fetch).

## `signLink(options, appSecret)`

Creates a signed, single-use link to the hosted connect or manage page.

```typescript theme={null}
import { signLink } from "@versoai/core";

const { url, token } = await signLink(
  {
    appId: "app_yourapp",
    userRef: "user_123",
    scopes: ["conversations:read"],
    purpose: "connect",          // or "manage"
    expiresInSeconds: 900,       // optional, max 900
  },
  process.env.VERSO_APP_SECRET!,
);
```

| Option | Type | Required | Description |
| - | - | - | - |
| `appId` | `string` | Yes | Your app id |
| `userRef` | `string` | Yes | Your identifier for the user. Returned in every webhook and used to query the API. |
| `scopes` | `string[]` | Yes | `["conversations:read"]` |
| `purpose` | `"connect" \| "manage"` | Yes | Which hosted page the link opens |
| `expiresInSeconds` | `number` | No | Link lifetime, default and maximum 900 |
| `baseUrl` | `string` | No | Default `https://connect.tryverso.ai` |

Returns `{ url, token }`. `url` is `https://connect.tryverso.ai/start?token=…` for `connect` and `…/manage?token=…` for `manage`.

Throws when `purpose` is not `connect` or `manage`, or when `expiresInSeconds` is zero, negative or above 900.

## `verifyWebhook(secret, signatureHeader, body, toleranceSec?)`

Checks the `X-Verso-Signature` header of a delivery. Synchronous, returns a boolean, never throws.

```typescript theme={null}
import { verifyWebhook } from "@versoai/core";

const ok = verifyWebhook(
  process.env.VERSO_WEBHOOK_SECRET!,
  req.get("x-verso-signature") ?? "",
  rawBody,       // the request body exactly as received
  300,           // optional tolerance in seconds, default 300
);
```

Pass the raw body, not a re-serialized object: the signature covers the bytes Verso sent. With Express, mount `express.raw({ type: "application/json" })` on the webhook route.

## Types

```typescript theme={null}
import type {
  WebhookEvent,             // { event, payload, deliveryId }, discriminated by event
  WebhookEventName,         // "connect.started" | "connection.created" | "data.imported" | "reauth.needed" | "data.deleted" | "connection.deleted"
  ConnectStartedPayload,
  ConnectionCreatedPayload,
  DataImportedPayload,
  ReauthNeededPayload,
  DataDeletedPayload,
  ConnectionDeletedPayload,
  SignLinkOptions,
  SignedLink,
  LinkPurpose,
} from "@versoai/core";
```

`WebhookEvent` narrows on `event`, so `event.payload` is typed inside a `switch`. Field-by-field descriptions are in the [webhooks guide](/guides/webhooks).

## Versions

**0.2.0** reduces the package to the surface above. The internal helpers that 0.1.0 exported (`createSupabaseClient`, `PgcryptoVaultProvider`, `markActive` and the other connection helpers, `enqueueWebhook`, `renderShell`, the database record types) were never meant for partners and are gone, along with the `@versoai/core/*` subpath exports. If you imported any of them, you were running Verso's server code: talk to us.
