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

# Getting Started

> Authenticate your users, send them a Setup Link, and make your first Context API and Tools API calls.

This guide walks through everything you need to make your first Agent OS requests: signing a Paragon User Token for your users, sending them a Setup Link to connect their apps, and calling the [Context API](https://docs.useparagon.com/agent-os/context/overview.md) and [Tools API](https://docs.useparagon.com/agent-os/tools/overview.md).

## Get started with your coding agent

The fastest way to set up Agent OS is with the Paragon Skills in your coding agent (Claude Code, Cursor, Codex, OpenCode, etc.). The skills give your agent the context it needs to set up authentication, create Setup Links, and call the Context and Tools APIs in your codebase.

Install them with the `npx skills` CLI:

```bash theme={null}
npx skills add useparagon/skills
```

Then ask your agent to set things up, for example:

```markdown Starter prompt theme={null}
Look at my app and set up Paragon Agent OS: sign Paragon User Tokens in my backend, add a way for users to open a Setup Link, and give my agent tools to search context and run Tools with the Context API and Tools API.
```

To set things up by hand, follow the steps below.

## 1. Get your Project ID and Signing Key

Open the **Overview** page in your Paragon dashboard. The **SDK Setup Keys** section has the 2 values you need, with a tab for each [environment](https://docs.useparagon.com/deploying-integrations/release-environments.md):

* **Project ID:** Identifies your project. Every Agent OS request includes it in its path. Click the copy button to copy it.
* **Signing Key:** The private key your backend uses to sign Paragon User Tokens. Click **Rotate** to generate a new key, and save it right away.

![The SDK Setup Keys section of the Paragon dashboard Overview page, showing the Project ID with a copy button and the Signing Key with a Rotate button](https://mintcdn.com/paragon/HBhYDQ0FDbZW5geP/assets/agent-os-sdk-setup-keys.webp?fit=max\&auto=format\&n=HBhYDQ0FDbZW5geP\&q=85\&s=9347edeee0e4a4a010f59c7907168ebb)

Store both in your project's `.env`:

```bash .env theme={null}
PARAGON_PROJECT_ID="your-project-id"
PARAGON_SIGNING_KEY="-----BEGIN PRIVATE KEY-----\n..."
```

> [!WARNING]
>
> Paragon doesn't store your Signing Key and can't show it to you again, so store it somewhere secure. Rotating the key invalidates the previous key for that environment.

Requests are sent to the [base URL](https://docs.useparagon.com/agent-os/overview.md#base-url) for your region, for example `https://agentos.useparagon.com` for US Cloud.

## 2. Sign a Paragon User Token

Agent OS identifies your users with a Paragon User Token: a JWT that your backend signs for each of your authenticated users. Every Context API and Tools API request is scoped to the Connected User in the token's `sub` claim.

Sign a JWT with RS256 that includes the `sub`, `aud`, `iat`, and `exp` claims. Agent OS requires the `aud` claim to be `useparagon.com/<your Project ID>`.

```js server.js theme={null}
import jwt from "jsonwebtoken";

function getParagonUserToken(user) {
  // JWT NumericDates are in seconds
  const currentTime = Math.floor(Date.now() / 1000);

  return jwt.sign(
    {
      sub: user.id, // Your user's or their company's ID
      aud: `useparagon.com/${process.env.PARAGON_PROJECT_ID}`,
      iat: currentTime,
      exp: currentTime + 60 * 60, // 1 hour from now
    },
    process.env.PARAGON_SIGNING_KEY,
    { algorithm: "RS256" },
  );
}
```

Send this token as a Bearer token on every Agent OS request:

```http theme={null}
Authorization: Bearer <Paragon User Token>
```

> [!NOTE]
>
> **Just for testing:** Use the [Paragon JWT Generator](https://jwt.useparagon.com/) to generate one-off tokens during development. Never use static tokens in production.

> [!NOTE]
>
> If you already use Auth0, Firebase, or a JWKS-compatible authentication server, you can use its tokens instead of signing your own. See [Using a managed authentication service](https://docs.useparagon.com/getting-started/installing-the-connect-sdk.md#using-a-managed-authentication-service).

## 3. Send your user a Setup Link

A Setup Link is a hosted page where your user connects their apps and chooses what content to sync, so you don't need to build any connection UI to get started.

Call [Create Setup Link](https://docs.useparagon.com/agent-os/context/create-setup-link.md) from your backend with the user's Paragon User Token. You can also authenticate with a Paragon API key that has the **Setup Links API** scope by passing the Connected User's ID as `endUserId`.

This endpoint is served from `https://zeus.useparagon.com` (US Cloud) or `https://zeus.eu.paragon.so` (EU Cloud), not the Agent OS base URL.

```js server.js theme={null}
const response = await fetch(
  `https://zeus.useparagon.com/projects/${projectId}/setup-links`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${getParagonUserToken(user)}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      expiresIn: 3600, // 1 hour, up to 24 hours
      integrations: ["googledrive", "sharepoint"], // Optional: limit the apps offered
    }),
  },
);

const { url } = await response.json();
```

Send the returned `url` to your user, for example by redirecting them to it or opening it in a new tab. On the hosted page, your user:

1. **Connects the apps** they want your agent to use. Apps they've already connected show a green check.

   ![The Setup Link app catalog, showing connected apps and available integrations grouped by category](https://mintcdn.com/paragon/hdX-Dot0wWXPQySZ/assets/context-setup-link-connect-apps.png?fit=max\&auto=format\&n=hdX-Dot0wWXPQySZ\&q=85\&s=e073abacc13e1992051bc2aef554b06f)

2. **Chooses what content to sync** from their knowledge sources, such as specific folders in Google Drive. Paragon syncs and indexes this content for the Context API.

   ![The Manage synced content page, showing discovery progress and a list of folders with checkboxes and sync status](https://mintcdn.com/paragon/hdX-Dot0wWXPQySZ/assets/context-setup-link-manage-content.png?fit=max\&auto=format\&n=hdX-Dot0wWXPQySZ\&q=85\&s=d5126dd9982a7e090e90d5f303de195d)

> [!WARNING]
>
> The Setup Link `url` contains a signed token. Treat it like a credential and share it only with the intended user.

## 4. Search your user's content

Once your user's content is synced and indexed, your agent can find relevant passages with [Search Context](https://docs.useparagon.com/agent-os/context/search.md):

```js theme={null}
const response = await fetch(
  `https://agentos.useparagon.com/api/context/projects/${projectId}/search`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${paragonUserToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: "q2 roadmap",
      topK: 10,
      identity: "user@example.com", // The account whose access applies
    }),
  },
);

const { results } = await response.json();
```

Results only include content that `identity` can access in the source app. Each passage includes a `pointer` that you can pass to [Read Segment Context](https://docs.useparagon.com/agent-os/context/read-segment.md) to read more of the surrounding text.

## 5. Find and run Tools

The Tools API lets your agent act in your user's connected apps. Rather than loading every available Tool into your agent, use [Search Tools](https://docs.useparagon.com/agent-os/tools/search.md) to find the ones relevant to the current task:

```js theme={null}
const response = await fetch(
  `https://agentos.useparagon.com/api/tools/projects/${projectId}/tools/search`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${paragonUserToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: "list open issues",
      connectedOnly: true, // Only Tools for apps your user has connected
      maxSideEffect: "read", // Only Tools that don't change data
    }),
  },
);

const { tools } = await response.json();
```

Each Tool is returned in a function-calling format that you can pass directly to your LLM. When your model calls a Tool, run it with [Run Tool](https://docs.useparagon.com/agent-os/tools/create-execution.md):

```js theme={null}
const response = await fetch(
  `https://agentos.useparagon.com/api/tools/projects/${projectId}/executions`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${paragonUserToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      intentName: toolCall.name,
      args: toolCall.arguments,
      outputMode: "auto",
    }),
  },
);

const execution = await response.json();
```

Small results are returned directly on `output.inline`. Large results are stored and returned as a `resultId` that your agent can page through with [Get Result Rows](https://docs.useparagon.com/agent-os/tools/get-result-rows.md) or [Get Result Content](https://docs.useparagon.com/agent-os/tools/get-result-content.md), keeping your agent's context small. See [Handling large results](https://docs.useparagon.com/agent-os/tools/overview.md#handling-large-results).

> [!TIP]
>
> Tools with a `sideEffect` other than `read` have `approvalRequired` set to `true`. Use this flag to ask your user to confirm before your agent runs a Tool that writes, deletes, or sends data. See [Side Effects](https://docs.useparagon.com/agent-os/tools/search.md#side-effects).

## Next steps

> **[Context API](https://docs.useparagon.com/agent-os/context/overview.md)**
>
> Learn how search results are organized and how user permissions are applied.

> **[Tools API](https://docs.useparagon.com/agent-os/tools/overview.md)**
>
> Learn how to filter Tools, wait for long-running Tools, and read large results.
