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

# Quickstart

Get from an API key to your first scheduled or published post.

This quickstart uses the SDK as the main path. The API and CLI expose the same
objects, but most integrations should start with the SDK.

<div className="quickstart-compact-callout">
  <Callout color="#22C55E">
    Want an agent to handle setup? [Agent quickstart](/docs/quickstart-agents)
  </Callout>
</div>

## What you will do

1. Create an API key.
2. Install the SDK.
3. Choose a profile key from your own app.
4. Generate an account connection URL.
5. Handle the connection return URL.
6. Use the connected account to publish a post.

## 1. Create an API key

Open the Kavenio dashboard and create an API key for your workspace.

```bash theme={null}
export KAVENIO_API_KEY="kv_live_..."
```

Keep this key server-side. Do not expose it in browser code, mobile apps, or
client-rendered pages.

## 2. Install the SDK

<CodeGroup>
  ```bash npm theme={null}
  npm install @kavenio/sdk
  ```

  ```bash yarn theme={null}
  yarn add @kavenio/sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @kavenio/sdk
  ```

  ```bash bun theme={null}
  bun add @kavenio/sdk
  ```
</CodeGroup>

## 3. Initialize the client

```ts theme={null}
import { Kavenio } from "@kavenio/sdk";

const kavenio = new Kavenio({
  apiKey: process.env.KAVENIO_API_KEY,
});
```

## 4. Choose a profile key

Use a stable key from your own app to group connected accounts, posts, media,
and queues for a brand, client, product, or workspace area. Pass that key as
`profileId` in Kavenio requests.

```ts theme={null}
const profileId = "customer_user_123";
```

## 5. Create a connect URL

Create a provider authorization URL and send the user to it. This example uses
LinkedIn, but the same flow works for other OAuth platforms.

```ts theme={null}
const { authorizationUrl } = await kavenio.connect.begin({
  profileId,
  platform: "linkedin",
  returnTo: "https://yourapp.com/settings/integrations",
});
```

Redirect the user to `authorizationUrl`. Kavenio handles the OAuth callback,
stores the provider credentials, and sends the user back to your `returnTo` URL
when the connection is complete.

### Return URL parameters

`returnTo` is your app URL. After the account is connected, Kavenio redirects
the user back to that URL with a GET request.

Kavenio appends these query parameters:

* `connect`: `connected` when the connection succeeded.
* `accountId`: the Kavenio connected account ID. Store this value.
* `profileId`: the profile key the account was attached to.
* `platform`: the connected platform, such as `linkedin`.

Example return URL:

```text theme={null}
https://yourapp.com/settings/integrations?connect=connected&accountId=acc_...&profileId=customer_user_123&platform=linkedin
```

You can also subscribe to the `account.connected` webhook to receive the
connected account data server-to-server. The return URL is best for updating the
user's current browser session; the webhook is best for durable backend
processing.

## 6. Handle the return URL

In your return route, read and store the connected account ID. This is how your
app links the Kavenio account to the current user, workspace, or integration
record.

```ts theme={null}
const url = new URL(request.url);

const accountId = url.searchParams.get("accountId");
const profileId = url.searchParams.get("profileId");
const platform = url.searchParams.get("platform");

if (url.searchParams.get("connect") !== "connected" || !accountId) {
  throw new Error("Account connection did not complete.");
}

await saveConnectedAccount({
  accountId,
  profileId,
  platform,
});
```

## 7. Publish a post

```ts theme={null}
const post = await kavenio.posts.create({
  profileId,
  content: "Shipping our first post with Kavenio.",
  platforms: [
    {
      platform: "linkedin",
      accountId,
    },
  ],
  publishNow: true,
});
```

To publish to every connected LinkedIn account in the profile, omit
`accountId`.

```ts theme={null}
await kavenio.posts.create({
  profileId,
  content: "Shipping to every connected LinkedIn account.",
  platforms: [
    {
      platform: "linkedin",
    },
  ],
  publishNow: true,
});
```

To schedule the post instead, replace `publishNow` with `scheduledFor`.

```ts theme={null}
await kavenio.posts.create({
  profileId,
  content: "Scheduled from Kavenio.",
  platforms: [
    {
      platform: "linkedin",
      accountId,
    },
  ],
  scheduledFor: "2026-07-01T14:00:00.000Z",
  timezone: "Europe/Rome",
});
```

## CLI check

The CLI is useful when an AI agent needs to verify the same setup without
writing application code.

```bash theme={null}
export KAVENIO_API_KEY="kv_live_..."

kavenio connect begin \
  --profile-id "customer_user_123" \
  --platform linkedin
kavenio accounts list --profile-id "customer_user_123"
```

Create a post from inline fields:

```bash theme={null}
kavenio posts create \
  --profile-id customer_user_123 \
  --content "Shipping our first post with Kavenio." \
  --publish-now \
  --platform linkedin:<account_id>
```

## Next steps

* Install your preferred SDK.
* Connect more platforms.
* Add media uploads.
* Set up webhooks for post and delivery events.
