> For the complete documentation index, see [llms.txt](https://planck-ai.gitbook.io/planck-ai-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://planck-ai.gitbook.io/planck-ai-docs/documentation/reference/python-example.md).

# Python Example

This page shows a simple Python example for working with the Planck AI API.

The example covers:

* Listing workspaces
* Selecting a workspace
* Listing documents
* Sending a stateless chat request
* Sending a chat request with a document
* Reading streamed Server-Sent Events responses

### Requirements

Install the `requests` package:

```bash
pip install requests
```

Set your API key as an environment variable:

```bash
export PLANCK_API_KEY="pk_live_your_key_here"
```

### Basic Python client

```python
import os
import json
import requests


API_BASE = "https://<your-planck-domain>/api/v1"
API_KEY = os.environ.get("PLANCK_API_KEY")

if not API_KEY:
    raise RuntimeError("Missing PLANCK_API_KEY environment variable")

HEADERS = {
    "X-API-Key": API_KEY,
    "Content-Type": "application/json",
}


def list_workspaces():
    """List all workspaces accessible to the API key owner."""
    response = requests.get(f"{API_BASE}/workspaces", headers=HEADERS)
    response.raise_for_status()
    return response.json()


def list_documents(workspace_id):
    """List documents in a workspace."""
    response = requests.get(
        f"{API_BASE}/documents/",
        headers=HEADERS,
        params={"workspace_id": workspace_id},
    )
    response.raise_for_status()
    return response.json()


def collect_sse_response(response):
    """
    Collect a streamed Server-Sent Events response.

    This simple parser collects text deltas and returns the final text.
    Production applications should handle multiple content block types.
    """
    text_parts = []
    credits_consumed = 0
    current_event = None

    for line in response.iter_lines():
        if not line:
            current_event = None
            continue

        line = line.decode("utf-8")

        if line.startswith("event: "):
            current_event = line.replace("event: ", "").strip()
            continue

        if not line.startswith("data: "):
            continue

        try:
            data = json.loads(line.replace("data: ", "", 1))
        except json.JSONDecodeError:
            continue

        if current_event == "content_block_delta":
            delta = data.get("delta", {})
            if "text" in delta:
                text_parts.append(delta["text"])

        if current_event == "message_stop":
            credits_consumed = data.get("credits_consumed", 0)

    return {
        "text": "".join(text_parts),
        "credits_consumed": credits_consumed,
    }


def chat(workspace_id, message, documents=None, database=None):
    """Send a stateless chat request."""
    payload = {
        "message": message,
        "stream": True,
    }

    chat_metadata = {}

    if documents:
        chat_metadata["documents"] = documents

    if database:
        chat_metadata["database"] = database

    if chat_metadata:
        payload["settings"] = {
            "chat_metadata": chat_metadata
        }

    response = requests.post(
        f"{API_BASE}/workspaces/{workspace_id}/chat",
        headers=HEADERS,
        json=payload,
        stream=True,
    )
    response.raise_for_status()
    return collect_sse_response(response)


def main():
    workspaces = list_workspaces()

    if not workspaces.get("data"):
        raise RuntimeError("No workspaces found for this API key")

    workspace = workspaces["data"][0]
    workspace_id = workspace["id"]

    print(f"Using workspace: {workspace['name']} ({workspace_id})")

    print("\nGeneral chat:")
    result = chat(workspace_id, "What can you help me with?")
    print(result["text"])
    print(f"Credits consumed: {result['credits_consumed']}")

    documents = list_documents(workspace_id)

    if documents.get("data"):
        document = documents["data"][0]
        document_id = document["id"]
        document_name = document["name"]

        print(f"\nChat with document: {document_name}")

        result = chat(
            workspace_id,
            "Summarize this document",
            documents={
                document_name: {
                    "id": document_id
                }
            },
        )

        print(result["text"])
        print(f"Credits consumed: {result['credits_consumed']}")
    else:
        print("\nNo documents found in this workspace")


if __name__ == "__main__":
    main()
```

### Database chat example

If your workspace has a database integration, you can pass the database integration reference in `chat_metadata`.

```python
database = {
    "workspace_id": "WORKSPACE_ID",
    "integration_id": "DATABASE_INTEGRATION_ID",
}

result = chat(
    workspace_id="WORKSPACE_ID",
    message="Show monthly revenue for the last two quarters.",
    database=database,
)

print(result["text"])
```

### Notes for production use

For production applications:

* Store API keys in a secure secrets manager
* Do not hardcode API keys in source code
* Handle non-text content blocks such as tables, charts, maps, and code
* Add retries for transient network errors
* Use exponential backoff for rate limits
* Log request IDs or timestamps for troubleshooting
* Validate that documents are processed before using them in chat

### Recommended next pages

* **Authentication** — learn how API keys work
* **Workspaces & Documents API** — list workspaces and documents
* **Chat API** — send stateless chat messages
* **Response Format** — handle streamed responses and content blocks


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://planck-ai.gitbook.io/planck-ai-docs/documentation/reference/python-example.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
