---
title: niyra_ask — synchronous Q&A
description: Ask Niyra a question and get an answer in a single round trip. Best for short, bounded queries.
url: /docs/api-tool-niyra-ask
lastUpdated: 2026-06-11
---

# niyra_ask — synchronous Q&A


# niyra_ask

A single-turn Q&A surface. You send a question, Niyra answers. No follow-up, no scheduling, no long-running work — for those, use `niyra_execute`.

## When to use

- "What's on my calendar tomorrow?"
- "Summarize my last conversation with Sarah."
- "Has Acme renewed their contract yet?"

If the question needs Niyra to actually *do* something (send an email, file a ticket, schedule a meeting), reach for `niyra_execute` instead.

## Endpoint

| Method | Path | Auth | Scope |
| ------ | ---- | ---- | ----- |
| POST   | `/v1/public/ask` | Bearer token (PAT or OAuth) | `niyra:ask` |

The same tool is also available via the MCP JSON-RPC surface at `POST /mcp` (method: `tools/call`, name: `niyra_ask`).

## Request

```json
{
  "question": "What did Sarah and I discuss last week?",
  "conversation_id": "optional-uuid",
  "channel_context": "optional string"
}
```

| Field | Type | Required | Notes |
| ----- | ---- | -------- | ----- |
| `question` | string | yes | The question to answer. Max 4000 chars. |
| `conversation_id` | uuid | no | Pin the answer to an existing thread. Omit to use the default thread. |
| `channel_context` | string | no | Short hint about where this came from ("from Slack via Zapier"). Surfaces in Niyra's reply tone. |

## Response

```json
{
  "answer": "You discussed the Q3 forecast and agreed to revisit next week.",
  "conversation_id": "8f3b…-uuid",
  "task_id": null,
  "elapsed_ms": 1840
}
```

If the answer can't be produced in the 30s budget, `task_id` is non-null and `answer` is null. Poll `niyra_get_task` until the task reaches a terminal state.

```json
{
  "answer": null,
  "conversation_id": "8f3b…-uuid",
  "task_id": "task_abc123",
  "elapsed_ms": 30000
}
```

## Code examples

### curl

```bash
curl -X POST https://api.niyra.ai/v1/public/ask \
  -H "Authorization: Bearer pat_…" \
  -H "Content-Type: application/json" \
  -d '{"question": "What is my next meeting?"}'
```

### JavaScript

```js
const res = await fetch("https://api.niyra.ai/v1/public/ask", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.NIYRA_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ question: "What is my next meeting?" }),
});
const data = await res.json();
console.log(data.answer ?? `Task spawned: ${data.task_id}`);
```

### Python

```python
import os, requests

r = requests.post(
    "https://api.niyra.ai/v1/public/ask",
    headers={"Authorization": f"Bearer {os.environ['NIYRA_TOKEN']}"},
    json={"question": "What is my next meeting?"},
)
data = r.json()
print(data.get("answer") or f"Task spawned: {data['task_id']}")
```

## Errors

| Status | Code | Meaning |
| ------ | ---- | ------- |
| 400 | `invalid_request` | Missing or empty `question`, or `question` > 4000 chars |
| 401 | `invalid_token` | Token revoked, expired, or unknown |
| 403 | `insufficient_scope` | Token lacks `niyra:ask` |
| 429 | `rate_limit_exceeded` | Per-token sliding-window budget exhausted; `Retry-After` header tells you when |

## Related

- [niyra_execute](/docs/api-tool-niyra-execute) — for tasks that need action, not just an answer
- [niyra_get_task](/docs/api-tool-niyra-get-task) — poll a spawned task
- [Scope catalog](/docs/api-scopes)
- [Rate limits](/docs/api-rate-limits)
