Assistant
The channel identities allowed to operate your naturali account.
Overview
The Naturali Assistant is the first-party agent you talk to on a messaging channel — Discord, WhatsApp, Slack — to run your account: inspect projects, check usage, manage agents and channels. This API is the consent layer in front of it: a grant is one channel identity authorized to act as one naturali account.
A grant is account-scoped and carries no project. It is a consent record, not a permission boundary — every project-scoped operation still resolves ownership per request, so a linked identity reaches exactly what you already see in the app and nothing more.
See the OpenAPI spec for the full endpoint and schema reference, or browse it rendered under API Reference → Assistant.
Data Model
AssistantGrant
| Field | Type | Description |
|---|---|---|
id | string | Public grant ID (agr_ prefix). |
channel | string | discord, whatsapp or slack. |
identifier | string | The channel identity, with its channel prefix — discord:112233…. |
display_name | string, nullable | The identity as its channel reported it. |
scopes | string[] | read, or manage for mutations. A link currently grants read. |
status | string | active or revoked. |
last_used_at | string (date-time), nullable | When the Assistant last acted under this grant. |
created_at | string (date-time) |
Key Concepts
Linking starts on the channel, not here
There is no endpoint that creates a link. Message the Assistant from an unlinked identity and it replies with a single-use link back to the app; that link lands on a confirmation screen which resolves the identity and, on an explicit click, redeems it.
Two calls make up that screen: GET /v1/assistant/link resolves a token
without consuming it, so the screen can name the identity before anyone
commits, and POST /v1/assistant/link redeems it. Reading is separate from
redeeming on purpose — a single-use nonce must not be spent by a URL scanner or
a browser prefetch.
One identity, one account
The same Discord user cannot be linked to two naturali accounts. Re-pointing an
identity means revoking the existing grant first, which is explicit and
auditable; redeeming a link for an identity that is already linked answers
409 identity_already_linked.
A dead link answers 400 with invalid_token (unknown or already redeemed) or
expired_token (it simply ran out of time — ask the Assistant for a fresh one).
Revoking is immediate
The grant is resolved on every inbound message, so revoking stops the Assistant on the next one rather than at some expiry. The row stays as consent history, and the identity is free to link again afterwards.
In the app, the account is the identity
The app's home screen talks to the Assistant through
POST /v1/assistant/messages and
reads the conversation back with
GET /v1/assistant/messages.
There is nothing to link: the signed-in account is who the Assistant acts as.
A credential confined to one project cannot hold the conversation, and a
deployment that serves no Assistant answers 503 assistant_unavailable.
Your turns are paid from your credit
Every turn the Assistant answers on a linked identity is charged to your
account's credit, at the same rate as managed model usage, and appears on your
ledger as Assistant usage. When your balance is below zero the Assistant
answers with a link to billing instead of running — in the app,
402 insufficient_credit — and answers again once you top up.
Examples
List the identities linked to your account:
- CLI
- SDK
- curl
naturali list-assistant-grants
const { data: page } = await naturali.assistant.listAssistantGrants();
curl https://api.naturali.ai/v1/assistant/grants \
-H "Authorization: Bearer $NATURALI_TOKEN"
Revoke one, disabling the Assistant for that identity:
- CLI
- SDK
- curl
naturali revoke-assistant-grant --grant-id agr_V1StGXR8Z5jdHi6B
await naturali.assistant.revokeAssistantGrant({
path: { grant_id: 'agr_V1StGXR8Z5jdHi6B' },
});
curl -X DELETE https://api.naturali.ai/v1/assistant/grants/agr_V1StGXR8Z5jdHi6B \
-H "Authorization: Bearer $NATURALI_TOKEN"
Message the Assistant as your account:
- CLI
- SDK
- curl
naturali send-assistant-message --text "List my projects."
const { data: turn } = await naturali.assistant.sendAssistantMessage({
body: { text: 'List my projects.' },
});
curl -X POST https://api.naturali.ai/v1/assistant/messages \
-H "Authorization: Bearer $NATURALI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text": "List my projects."}'