Skip to main content

🚀 Linkup Python SDK

PyPI version License: MIT PyPI - Downloads Discord

A Python SDK for the Linkup API, allowing easy integration with Linkup's services in any Python application. 🐍

Checkout the official API documentation and SDK documentation for additional details on how to benefit from Linkup services to the full extent. 📝

🌟 Features

  • ✅ Simple and intuitive API client.
  • 🔍 Supports Linkup search, fetch, research, and task workflows.
  • ⚡ Support synchronous and asynchronous calls.
  • 🔒 Handle authentication and request management.
  • 💳 Built-in x402 payment protocol support for on-chain payments.

📦 Installation

Simply install the Linkup Python SDK as any Python package, for instance using pip:

pip install linkup-sdk

To use the x402 payment protocol (on-chain payments via EVM), install the optional x402 extras:

pip install linkup-sdk[x402]

🛠️ Usage

Setting Up Your Environment

  1. 🔑 Obtain an API Key:

    Sign up on Linkup to get your API key.

  2. ⚙️ Set-up the API Key:

    Option 1: Export the LINKUP_API_KEY environment variable in your shell before using the Python SDK.

    export LINKUP_API_KEY=<your-linkup-api-key>
    

    Option 2: Set the LINKUP_API_KEY environment variable directly within Python, using for instance os.environ or python-dotenv with a .env file (python-dotenv needs to be installed separately in this case), before creating the Linkup Client.

    import os
    import linkup
    
    os.environ["LINKUP_API_KEY"] = "<your-linkup-api-key>"
    # or dotenv.load_dotenv()
    client = linkup.Client()
    ...
    

    Option 3: Pass the Linkup API key to the Linkup Client when creating it.

    import linkup
    
    client = linkup.Client(api_key="<your-linkup-api-key>")
    ...
    

📋 Examples

📝 Search

The search function can be used to performs web searches. It supports three different complexity modes, through the depth parameter:

  • "fast" (beta), for sub-second responses to simple, focused queries (must be keyword-based)
  • "standard", for single-iteration agentic search that can interpret the query, run parallel sub-searches, and scrape one URL while remaining fast
  • "deep", for slower, more agentic and complex responses, suited to 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?")

The search function also supports three output types, through the output_type parameter:

  • with "searchResults", the search will return a list of relevant documents
  • with "sourcedAnswer", the search will return a concise answer with sources
  • with "structured", the search will return a structured output according to a user-defined object schema
import linkup

client = linkup.Client()  # API key can be read from the environment variable or passed as an argument
search_response: linkup.SourcedAnswer = client.search(
    query="What are the 3 major events in the life of Abraham Lincoln?",
    depth="deep",  # "fast" (beta), "standard", or "deep"
    output_type="sourcedAnswer",  # "searchResults" or "sourcedAnswer" or "structured"
    structured_output_schema=None,  # must be filled if output_type is "structured"
)
print(search_response.model_dump())

Which prints:

{
  answer="The three major events in the life of Abraham Lincoln are: 1. ...",
  sources=[
    {
      "name": "HISTORY",
      "url": "https://www.history.com/topics/us-presidents/abraham-lincoln",
      "snippet": "Abraham Lincoln - Facts & Summary - HISTORY ...",
      "favicon": "https://www.history.com/favicon.ico",
    },
    ...
  ]
}

Check the code or the official documentation for the detailed list of available parameters.

🪝 Fetch

The fetch function can be used to retrieve the content of a given web page in a cleaned up markdown format, together with the website's favicon URL.

You can use the render_js flag to execute the JavaScript code of the page before returning the content, set include_raw_content to include the raw page content and its content type in the output, or set mode to "pro" for significantly higher success rates on hard-to-retrieve pages. You can also pass an object JSON schema, with optional instructions, to extract structured data.

import linkup

client = linkup.Client()  # API key can be read from the environment variable or passed as an argument
fetch_response: linkup.FetchResponse = client.fetch(
    url="https://docs.linkup.so",
    render_js=True,
    include_raw_content=True,
    mode="pro",
    schema={
        "type": "object",
        "properties": {"title": {"type": "string"}},
    },
    instructions="Extract the page title.",
)
print(fetch_response.model_dump())

Which prints:

{
  "markdown": "The production-grade web search API for AI.",
  "favicon": "https://favicons.linkup.so?domain=docs.linkup.so",
  "raw_content": "<!DOCTYPE html><html lang=\"en\"><head>...</head><body>...</body></html>",
  "content_type": "html",
  "data": {"title": "The production-grade web search API for AI."},
}

Check the code or the official documentation for the detailed list of available parameters.

🧠 Research

The research function creates an asynchronous research task. You can then use get_research or list_research to inspect it later.

import linkup

client = linkup.Client()
research_task: linkup.ResearchTask = client.research(
    query="What changed in the AI browser market this quarter?",
    output_type="sourcedAnswer",
)
print(research_task.id)

🗂️ Tasks

The create_tasks function lets you submit mixed search, fetch, and research jobs in a single batch, then inspect them through get_task or list_tasks.

import linkup

client = linkup.Client()
tasks = client.create_tasks(
    [
        linkup.SearchTaskInput(
            query="Linkup latest product updates",
            depth="deep",
            output_type="sourcedAnswer",
        ),
        linkup.FetchTaskInput(
            url="https://docs.linkup.so",
        ),
    ]
)
print([task.id for task in tasks])

⌛ Asynchronous Calls

All the Linkup main functions come with an asynchronous counterpart, with the same behavior and the same name prefixed by async_ (e.g. async_search for search). This should be favored in production use cases to avoid blocking the main thread while waiting for the Linkup API to respond. This makes possible to call the Linkup API several times concurrently for instance.

import asyncio

import linkup

async def main() -> None:
    client = linkup.Client()  # API key can be read from the environment variable or passed as an argument
    search_response: linkup.SourcedAnswer = await client.async_search(
        query="What are the 3 major events in the life of Abraham Lincoln?",
        depth="deep",  # "fast" (beta), "standard", or "deep"
        output_type="sourcedAnswer",  # "searchResults" or "sourcedAnswer" or "structured"
        structured_output_schema=None,  # must be filled if output_type is "structured"
    )
    print(search_response.model_dump())

asyncio.run(main())

Which prints:

{
  answer="The three major events in the life of Abraham Lincoln are: 1. ...",
  sources=[
    {
      "name": "HISTORY",
      "url": "https://www.history.com/topics/us-presidents/abraham-lincoln",
      "snippet": "Abraham Lincoln - Facts & Summary - HISTORY ..."
      "favicon": "https://www.history.com/favicon.ico",
    },
    ...
  ]
}

💳 x402 Payment Protocol

The SDK supports the x402 payment protocol, allowing clients to automatically handle HTTP 402 responses by signing and retrying requests with on-chain payments via EVM-compatible networks (currently Base). This can be used as an alternative to API key authentication.

Create an eth_account LocalAccount compatible with Base (Ethereum):

from eth_account import Account

account = Account.from_key("<YOUR WALLET PRIVATE KEY>")
from eth_account import Account

Account.enable_unaudited_hdwallet_features()
account = Account.from_mnemonic("<YOUR MNEMONIC PHRASE>")

Then pass it to create_x402_signer and use the Linkup client:

import linkup
from linkup.x402 import create_x402_signer

signer = create_x402_signer(account)
client = linkup.Client(x402_signer=signer)

result = client.search(
    query="What is x402?",
    depth="standard",
    output_type="sourcedAnswer",
)
print(result.answer)

Metadata

Release files for linkup-sdk 0.22.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for linkup-sdk 0.22.0
File Size Uploaded
linkup_sdk-0.22.0.tar.gz 196.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for linkup-sdk 0.22.0
File Interpreter ABI Platform
linkup_sdk-0.22.0-py3-none-any.whl Python 3 none any Details

Total release size: 218.2 kB

Release files / linkup_sdk-0.22.0.tar.gz

Download URL linkup_sdk-0.22.0.tar.gz
Size 196.3 kB
Tags Source
SHA-256 checksum
How to use checksums
10672899aaa483e9b6b624220fc3ccfc34fc6d5ec3bf8cb65e9074fabc3f14a4
BLAKE2b-256 checksum
How to use checksums
87bdbc54a7c750d82a59a33a34c257ad14f02ef528caf6d2e14480b17c43a5e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.

Transparency log

Release files / linkup_sdk-0.22.0-py3-none-any.whl

Download URL linkup_sdk-0.22.0-py3-none-any.whl
Size 21.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
22165fab5a0f77090d44b0f6c386e0600300bbb94bd68361abfc3966a14d0263
BLAKE2b-256 checksum
How to use checksums
9ffa46b1eeb6640de12c8236929d0488d43e56598ba4258a962d339535978a89
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.

Transparency log

Release history Release notifications | RSS feed

0.23.1

2 release files

0.23.0

2 release files

This release

0.22.0 This release

2 release files

0.21.0

2 release files

0.19.0

2 release files

0.18.4

2 release files

0.18.3

2 release files

0.17.0

2 release files

0.16.0

2 release files

0.15.0

2 release files

0.14.2

2 release files

0.14.1

2 release files

0.14.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.11

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page