# 🚀 Linkup JS/TS SDK [![npm package](https://badge.fury.io/js/linkup-sdk.svg)](https://www.npmjs.com/package/linkup-sdk) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![downloads](https://img.shields.io/npm/dm/linkup-sdk.svg)](https://www.npmjs.com/package/linkup-sdk) A JS/TS SDK for the [Linkup API](https://linkup-api.readme.io/reference/getting-started), allowing easy integration with Linkup's services. ## 🌟 Features - ✅ **Simple and intuitive API client.** - 🔍 **Supports `standard`, `deep`, and beta `fast` search depths.** - 🧠 **Supports asynchronous research tasks and batched task workflows.** - 🔒 **Handles authentication and request management.** ## 📦 Installation > **Requires Node.js >= 22** Simply install the Linkup JS SDK using `npm` or any other package manager: ```bash npm i linkup-sdk ``` ## 📚 Documentation Find the complete documentation [here](https://docs.linkup.so/pages/sdk/js/js). ## 🛠️ Usage ### Setting Up Your Environment #### 1. **🔑 Obtain an API Key:** Sign up on [Linkup](https://app.linkup.so) to get your API key. #### 2. **⚙️ Set-up the API Key:** Pass the Linkup API key to the Linkup Client when creating it. ```typescript import { LinkupClient } from 'linkup-sdk'; const client = new LinkupClient({ apiKey: '', }); ``` ### 📋 Search Endpoint All search queries can be used with three depth modes: - with beta `fast` `depth`, the search is optimized for the quickest turnaround on lightweight queries - with `standard` `depth`, the search will be straightforward and fast, suited for relatively simple queries (e.g. "What's the weather in Paris today?") - with `deep` `depth`, the search will use an agentic workflow, which makes it in general slower, but it will be able to solve more complex queries (e.g. "What is the company profile of LangChain accross the last few years, and how does it compare to its concurrents?") You can also refine search requests with: - `includeDomains` and `excludeDomains` domain filters (`includeDomains` accepts up to 100 entries) - `fromDate` and `toDate` ISO date filters - `maxResults` to cap the number of returned results - `includeInlineCitations` for `sourcedAnswer` output - `includeSources` for `structured` output responses #### 📝 Example standard search query ```typescript import { LinkupClient } from 'linkup-sdk'; const client = new LinkupClient({ apiKey: '', }); const askLinkup = () => client.search({ query: 'Can you tell me which women were awared the Physics Nobel Prize', depth: 'standard', outputType: 'sourcedAnswer', }); askLinkup() .then(console.log) .catch(console.error); ``` ### ⬇️ Fetch Endpoint You can use the fetch endpoint to retrieve the content of a given URL in clean `markdown` format. Use `renderJs` to execute the JavaScript code of the page before returning the content. Use `includeRawHtml` to get the raw HTML of the page. Use `extractImages` to get an extracted list of images from the page. #### 📝 Example ```typescript import { LinkupClient } from 'linkup-sdk'; const client = new LinkupClient({ apiKey: '', }); const fetchLinkup = async () => client.fetch({ url: 'https://docs.linkup.so', renderJs: true, }); fetchLinkup() .then(console.log) .catch(console.error); ``` ### 🧠 Research Endpoint Use `research` to create an asynchronous research task, then poll it later or list recent runs. The research endpoint also supports: - `mode`: `answer`, `auto`, `investigate`, or `research` - `reasoningDepth`: `S`, `M`, `L`, or `XL` - `listResearch({ page, pageSize, sortBy, sortDirection })` to page through recent runs ```typescript import { LinkupClient } from 'linkup-sdk'; const client = new LinkupClient({ apiKey: '', }); const task = await client.research({ query: 'Research the current state of the semiconductor market, covering key market dynamics, major industry players and their strategic positioning, recent analyst sentiment, and the main bull and bear cases for the sector. Ground the report in sourced, factual information.', outputType: 'sourcedAnswer', mode: 'auto', reasoningDepth: 'L', }); const latest = await client.getResearch(task.id); const recent = await client.listResearch({ page: 1, pageSize: 10, sortDirection: 'desc' }); ``` ### 🗂️ Tasks Endpoint Use `createTasks` to submit mixed `search`, `fetch`, and `research` jobs in one batch, then inspect them through `listTasks` or `getTask`. `createTasks` accepts up to 100 tasks per batch. `listTasks` supports pagination and filtering via `page`, `pageSize`, `sortBy`, `sortDirection`, `status`, and `type`. ```typescript import { LinkupClient } from 'linkup-sdk'; const client = new LinkupClient({ apiKey: '', }); const tasks = await client.createTasks([ { type: 'search', input: { query: 'Linkup latest product updates', depth: 'deep', outputType: 'sourcedAnswer', }, }, { type: 'fetch', input: { url: 'https://docs.linkup.so', }, }, ]); console.log(tasks.map(task => task.id)); const queued = await client.listTasks({ status: ['pending', 'processing'], type: ['search', 'research'], sortBy: 'updatedAt', sortDirection: 'desc', page: 1, pageSize: 20, }); console.log(queued.quota); ``` ### 💳 X402 Payment Protocol The SDK supports the [X402 payment protocol](https://www.x402.org/), allowing you to pay for API calls with on-chain transactions instead of an API key. #### Prerequisites Install the required peer dependencies: ```bash npm i viem @x402/core @x402/evm ``` #### 📝 Example Create a viem `LocalAccount` compatible with Base (Ethereum): ```typescript import { privateKeyToAccount } from 'viem/accounts'; const account = privateKeyToAccount(''); ``` ```typescript import { mnemonicToAccount } from 'viem/accounts'; const account = mnemonicToAccount(''); ``` Then pass it to `createX402Signer` and use the Linkup client: ```typescript import { LinkupClient } from 'linkup-sdk'; import { createX402Signer } from 'linkup-sdk/x402'; const signer = createX402Signer(account); const client = new LinkupClient({ signer }); const response = await client.search({ query: 'What is the X402 payment protocol?', depth: 'standard', outputType: 'sourcedAnswer', }); ```