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

# Usage

> Reference for every ReyGrid Python SDK client method: chat, conversations, messages, pagination, and tool calls.

Every method has a synchronous form and an `async_` form (for example `chat()` and `async_chat()`) with identical parameters. Responses are typed dataclasses; field names match the API (`conversationId`, `quotaLimit`, …).

```python theme={"system"}
from reygrid import ReyGrid

client = ReyGrid(api_key="your-api-key")
```

## Health and usage

<AccordionGroup>
  <Accordion title="ping() → PingResponse" defaultOpen>
    `GET /ping`. No API key required.

    ```python theme={"system"}
    ping = client.ping()
    print(ping.status, ping.service, ping.version)   # UP ...
    print(ping.metadata.uptime if ping.metadata else None)
    ```

    `PingResponse`: `success`, `status` (`"UP"` or `"DOWN"`), `service`, `version`, `metadata` (`uptime`, `timestamp`).
  </Accordion>

  <Accordion title="validate() → ValidateResponse">
    `GET /validate`.

    ```python theme={"system"}
    v = client.validate()
    print(v.valid, v.usage.total, v.usage.quotaLimit)
    ```
  </Accordion>

  <Accordion title="get_usage() → Usage">
    Shortcut for `validate().usage`.

    ```python theme={"system"}
    usage = client.get_usage()
    print(f"{usage.total} / {usage.quotaLimit}")
    ```
  </Accordion>
</AccordionGroup>

## Chat

### `chat(agent_id, message, *, conversation_id=None, user_id=None, tools=None, results=None) → ChatResponse`

Sends a message to an agent and returns the full reply (`POST /agents/{agentId}/chat`).

<ParamField path="agent_id" type="str" required>The agent ID.</ParamField>
<ParamField path="message" type="str" required>The user message.</ParamField>
<ParamField path="conversation_id" type="str">Existing conversation. Ignored when `user_id` is set.</ParamField>
<ParamField path="user_id" type="str">Stable user identifier for a persistent conversation.</ParamField>
<ParamField path="tools" type="list[dict]">Tool definitions. Pass plain dicts. See [Tool calling](/rest-api/tool-calling).</ParamField>
<ParamField path="results" type="list[dict]">Tool results: `{"toolCallId": ..., "output": "<string>"}`.</ParamField>

```python theme={"system"}
reply = client.chat(
    "{AgentId}",
    "Check my current subscription",
    user_id="user-42",
    tools=[{
        "type": "function",
        "function": {
            "name": "check_subscription",
            "instructions": "Opens the customer's current plan, renewal date, and payment status.",
            "parameters": {
                "type": "object",
                "properties": {"userId": {"type": "string", "description": "The customer user id"}},
                "required": ["userId"],
            },
        },
    }],
)

print(reply.output.reply.content)
print(reply.output.finish_reason, reply.messageId, reply.conversationId)
print(reply.usage.credits)
```

**Returns** `ChatResponse`: `success`, `messageId`, `output` (`reply.id`, `reply.content`, `finish_reason`), `usage.credits`, and optional `conversationId`, `userId`.

<Note>
  `chat()` does not take a `stream` argument. For streaming use [`stream_chat()`](/integrations/python/streaming).
</Note>

### Sending tool results

```python theme={"system"}
import json

reply = client.chat(
    "{AgentId}",
    "What is the status of my account?",
    user_id="user-42",
    tools=[check_subscription_tool],
    results=[{
        "toolCallId": "call_xyz",
        "output": json.dumps({"plan": "pro", "status": "active"}),
    }],
)
```

## Conversations

### `list_conversations(agent_id, page=1, size=20) → ConversationsResponse`

`size` is capped at 100.

```python theme={"system"}
res = client.list_conversations("{AgentId}", page=1, size=20)
for c in res.conversations:
    print(c.conversationId, c.userId, c.messagesCount, c.createdAt)
print(res.pagination.hasNextPage, res.pagination.totalConversations)
```

### `delete_conversation(agent_id, conversation_ref) → DeleteMessagesResponse`

`conversation_ref` is a conversation ID or a persistent user ID.

```python theme={"system"}
res = client.delete_conversation("{AgentId}", "user-42")
print(res.deletedMessages.count)
```

## Messages

### `list_messages(agent_id, conversation_ref, page=1, size=20) → MessagesResponse`

```python theme={"system"}
res = client.list_messages("{AgentId}", "user-42", page=1, size=50)
for m in res.messages:
    print(m.role, m.content)
    for call in m.tool_calls or []:
        print("  tool call:", call.id, call.function.name, call.status)
```

### `delete_message(agent_id, conversation_ref, message_id, cascade=False) → DeleteMessagesResponse`

With `cascade=True`, the message immediately following is deleted too.

```python theme={"system"}
res = client.delete_message("{AgentId}", "user-42", "MESSAGE_ID", cascade=True)
print(res.deletedMessages.count)
```

## Tool calls

### `cancel_tool_call(agent_id, conversation_ref, tool_call_id) → CancelToolResponse`

```python theme={"system"}
res = client.cancel_tool_call("{AgentId}", "user-42", "call_xyz")
print(res.canceled)
```

A `404` raises `ReyGridNotFoundError`; a `409` (cannot be canceled) raises `ReyGridConflictError`.

## Agents

### `list_agents()` · `get_agent(agent_id)` · `update_agent(agent_id, *, name=None, instructions=None, model=None)`

```python theme={"system"}
agents = client.list_agents().agents  # the agents this key can use
agent = client.get_agent("{AgentId}").agent
print(agent.sources, agent.storage.used, agent.storage.limit)

client.update_agent("{AgentId}", instructions="Answer in a friendly tone.")
```

## Knowledge

```python theme={"system"}
client.add_text_source("{AgentId}", "Refund policy", "…")
client.add_qa_source("{AgentId}", "Do you ship abroad?", "…")
client.upload_file("{AgentId}", "handbook.pdf")
print(client.crawl_website("{AgentId}", "https://docs.example.com").pagesCrawled)

sources = client.list_sources("{AgentId}", type="text", search="refund").sources
client.delete_source("{AgentId}", sources[0].id)
```

`upload_file` accepts a path, `bytes` (pass `filename`) or an open binary file. Uploads and crawls wait for indexing, so they use a 10-minute timeout by default (`timeout=` to change it). See [Knowledge & search](/rest-api/knowledge).

## Search, feedback, models and usage

```python theme={"system"}
results = client.search("{AgentId}", "How do I get a refund?", limit=3).results

client.rate_message("{AgentId}", "user-42", "msg_abc123", "up")

models = client.list_models().models
report = client.get_usage_report(days=7)  # balance, totals, daily, agents
print(report.period.from_)  # "from" is exposed as from_
```

`get_usage_report()` is the account report from `GET /usage`; `get_usage()` still returns this key's usage from `/validate`.

## Pagination helpers

`paginate_conversations(agent_id, size=20)` and `paginate_messages(agent_id, conversation_ref, size=20)` return a `Paginator`. Iterating it yields a `PaginatedResult` per page, with `.data` (the items) and `.pagination`.

```python theme={"system"}
for page in client.paginate_conversations("{AgentId}", size=50):
    for convo in page.data:
        print(convo.conversationId, convo.messagesCount)

for page in client.paginate_messages("{AgentId}", "user-42"):
    for msg in page.data:
        print(msg.role, msg.content)
```

Async iteration uses the `async_` variants:

```python theme={"system"}
async for page in client.async_paginate_conversations("{AgentId}"):
    for convo in page.data:
        print(convo.conversationId)
```

<Warning>
  `Paginator.all()` is synchronous and only works with `paginate_conversations` / `paginate_messages`. For the async variants, iterate with `async for`.
</Warning>

## Async usage

```python theme={"system"}
import asyncio
from reygrid import ReyGrid

async def main():
    async with ReyGrid(api_key="your-api-key") as client:
        reply = await client.async_chat("{AgentId}", "Hello!", user_id="user-42")
        print(reply.output.reply.content)

asyncio.run(main())
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.