Skip to content

Tenant API

This page documents every tenant-level operation: fetching your tenant, creating one, updating settings, deleting it, and generating an API key. See Multi-Tenancy for the conceptual model (what a tenant is, how row-level isolation works) and Authentication for the full JWT/API-key auth model — this page cross-links there rather than repeating it.

Every request must include the x-huat-platform: customer header.

Returns the tenant belonging to the authenticated caller.

Auth required: JWT (AuthJwtGuard).

Arguments: None.

Returns: TenantDto (nullable — returns null for a user not yet assigned to a tenant, e.g. immediately after register)

FieldTypeNotes
idInt!
nameString!
planTenantPlanEnum!DEV, PRO, or ENTERPRISE
isSuspendedBoolean!
llmProviderOverrideLlmProviderTypePilot — tenant-wide default LLM provider for every agent that has no agent-level override of its own. See Agents: LLM provider override.
llmModelOverrideStringPilot — only meaningful when llmProviderOverride is BEDROCK_MANTLE. Same section.
allowedLlmModels[String!]Read-only. null means no restriction (the default). Otherwise the model ids this tenant may use, optionally provider:<PROVIDER> entries. Set by a Wetel administrator. See Restricting which models a tenant can use.
primaryBillingAccountPrimaryBillingAccountEnum!WEBBYX_ONE or WETEL — which system bills this tenant’s usage. Set via setPrimaryBillingAccount.
createdAtDateTime!
updatedAtDateTime!
deletedAtDateTimeSet once the tenant has been soft-deleted

Example request:

query MyTenant {
myTenant {
id
name
plan
isSuspended
}
}
Terminal window
curl https://api.wetel.dev/graphql \
-H "Content-Type: application/json" \
-H "x-huat-platform: customer" \
-H "Authorization: Bearer <YOUR_API_KEY>" \
-d '{"query":"query { myTenant { id name plan isSuspended } }"}'

Example response:

{
"data": {
"myTenant": {
"id": 7,
"name": "Acme Support",
"plan": "PRO",
"isSuspended": false
}
}
}

Creates a new tenant.

Auth required: JWT (AuthJwtGuard).

Arguments:

ArgumentTypeRequired
inputCreateTenantInput!Yes

CreateTenantInput:

FieldTypeNotes
nameString!Required
planTenantPlanEnumOptional — DEV, PRO, or ENTERPRISE
regionStringOptional
llmProviderOverrideLlmProviderTypeOptional, pilot — see Agents: LLM provider override.
llmModelOverrideStringOptional, pilot — same section.

Returns: TenantDto! (see shape above)

Example:

mutation CreateTenant($input: CreateTenantInput!) {
createTenant(input: $input) {
id
name
plan
}
}
{ "input": { "name": "Acme Support", "plan": "DEV" } }

Updates the caller’s own tenant.

Auth required: JWT (AuthJwtGuard).

Arguments:

ArgumentTypeRequired
inputUpdateTenantInput!Yes

UpdateTenantInput (every field optional — send only what is changing):

FieldTypeNotes
nameString
planTenantPlanEnum
regionString
isSuspendedBoolean
llmProviderOverrideLlmProviderTypePilot — supports detach-to-default: omit to leave unchanged, send null to clear. See Agents: LLM provider override.
llmModelOverrideStringPilot — same detach-to-default behavior.

Returns: TenantDto!

Example:

mutation UpdateTenant($input: UpdateTenantInput!) {
updateTenant(input: $input) {
id
name
plan
}
}
{ "input": { "name": "Acme Support Inc." } }

Soft-deletes the caller’s own tenant.

Auth required: JWT (AuthJwtGuard).

Arguments: None.

Returns: Boolean!

Example:

mutation DeleteTenant {
deleteTenant
}
Terminal window
curl https://api.wetel.dev/graphql \
-H "Content-Type: application/json" \
-H "x-huat-platform: customer" \
-H "Authorization: Bearer <YOUR_API_KEY>" \
-d '{"query":"mutation { deleteTenant }"}'

Generates a new API key for the current tenant, for authenticating server-to-server operations that don’t use a JWT (for example, the embed SDK’s sdkStart entry point, or the embed query).

For the full picture of how API keys fit into the overall auth model (JWT vs. API key vs. avatar token), see Authentication.

Auth required: JWT (AuthJwtGuard).

Arguments: None.

Returns: GenerateApiKeyResult!

FieldTypeNotes
keyString!The raw API key — shown only this once
warningString!A human-readable reminder about one-time visibility and invalidation of the previous key

Example request:

mutation GenerateApiKey {
generateApiKey {
key
warning
}
}
Terminal window
curl https://api.wetel.dev/graphql \
-H "Content-Type: application/json" \
-H "x-huat-platform: customer" \
-H "Authorization: Bearer <YOUR_LOGIN_ACCESS_TOKEN>" \
-d '{"query":"mutation { generateApiKey { key warning } }"}'

Example response:

{
"data": {
"generateApiKey": {
"key": "<YOUR_API_KEY>",
"warning": "Store this key now — it will not be shown again, and generating a new key invalidates this one immediately."
}
}
}

Returns the LLM spend for the caller’s own tenant for one calendar month (the current month by default, or a past month via yearMonth), the tenant’s monthly spend cap (by plan tier — see LLM API: Monthly spend cap), and a call-count breakdown by model and operation. Backs the dashboard’s Developers page.

Covers all of the tenant’s LLM usage — agent sessions, workflow runs, evaluation, and the LLM API — not just one source. It cannot be broken down by individual named API key; usage is tracked per-tenant only (AiUsageEntity has no apiKeyId column today).

Auth required: JWT (AuthJwtGuard).

Arguments:

ArgumentTypeNotes
yearMonthStringOptional calendar month (UTC) as YYYY-MM, to look at a previous month. Defaults to the current month. A future or malformed value returns 400.

Every figure in the response — cost, credits, buckets and breakdown — covers that one month.

Returns: ApiUsageSummaryDto!

FieldTypeNotes
yearMonthString!The month (YYYY-MM, UTC) every figure covers — your yearMonth argument, or the current month.
costThisMonthUsdFloat!This tenant’s total LLM spend for yearMonth, across all sources (the name predates the yearMonth argument).
monthlySpendCapUsdFloat!The plan-tier cap this tenant is measured against — same limit generateText/startTextGeneration enforce.
breakdown[ApiUsageBreakdownItemDto!]!One row per (model, operation) pair in yearMonth only, most-called first, each with count, costUsd and creditsUsed. model is not always an LLM model — tool, voice and avatar usage appear here too, so label the column “Item”.
usageByBucket[UsageBucketDto!]!The same month split into four consumption buckets (AI_CREDITS, TTS, STT, AVATAR), each with callCount, costUsd and creditsUsed. See Usage buckets below.

usageByBucket always has the four buckets, in this order of meaning:

  • AI_CREDITS: language-model work (generate, embed, evaluate) plus tool and action calls. Tool-call credits are exact; the generate/embed/evaluate part is an approximation, as described under creditsUsedThisMonthApprox.
  • TTS and STT: speech synthesis and recognition, exact figures.
  • AVATAR: covers browser-rendered 3D avatar replies only. Usage of a hosted video avatar (avatarBackend: HOSTED_API) is not tracked here yet, so a low or zero AVATAR total does not mean low real avatar usage if your agents use the hosted backend.

Each breakdown row carries creditsUsed: Int!, the credits that item consumed in yearMonth, worked out by the same rule as the bucket the item belongs to. costUsd stays on every row, so existing integrations keep working. Customer-facing dashboards show credits only.

  • Approximate for LLM work. Credits for generate, embed and evaluate rows are an approximation derived from cost.
  • Real charges for everything else. Tool calls (per-action creditsPerCall overrides included), speech (TTS/STT) and avatar rendering are charged at fixed per-unit rates.
  • Rows add up to their bucket. Within one bucket, the rows’ creditsUsed sum exactly to that bucket’s creditsUsed. Because credits are rounded per operation and then split across that operation’s rows, a single row can differ by at most 1 credit from rounding its own cost alone (two tiny speech rows can read 1 and 0).
  • A row with no bucket reads 0. An operation the pricing model does not charge for has no credits to report.
  • The headline is a different calculation. creditsUsedThisMonthApprox applies one blended rule to the whole month’s cost, so it will not equal the sum of the buckets.

Example request:

query ApiUsageSummary {
apiUsageSummary {
costThisMonthUsd
monthlySpendCapUsd
breakdown {
model
operation
count
costUsd
creditsUsed
}
}
}
# A previous month:
# apiUsageSummary(yearMonth: "2026-08") { ... }
Terminal window
curl https://api.wetel.dev/graphql \
-H "Content-Type: application/json" \
-H "x-huat-platform: customer" \
-H "Authorization: Bearer <YOUR_JWT>" \
-d '{"query":"query { apiUsageSummary { costThisMonthUsd monthlySpendCapUsd breakdown { model operation count costUsd creditsUsed } } }"}'
tenantCostByAgent(window: ActivityWindowPreset = MONTH_TO_DATE, from: DateTime, to: DateTime): TenantCostByAgentDto!

Workspace owner only (anyone else gets FORBIDDEN). What each AI employee cost in a window: the model calls attributed to it, highest cost first. window is a preset ending now (default MONTH_TO_DATE, UTC); alternatively send from and to together (from inclusive, to exclusive, at most 92 days, to not in the future), which override window.

Off by default. Attribution (which AI employee a model call belongs to) is switched on by a platform setting that is off until Wetel enables it. While it is off, agents is empty and attributionEnabled is false. Calls recorded before it was switched on, and calls made outside an AI employee’s run, carry no agent and are counted as unattributed.

FieldTypeDescription
agents[AgentCostDto!]!One entry per agent with attributed calls in the window, highest cost first. Agents with no spend are not listed.
attributedCostUsdFloat!Sum of costUsd over agents: attributed spend only, not the workspace total.
attributedCreditsApproxInt!Approximate credits for attributedCostUsd.
unattributedCallsInt!Calls in the window with no agent attached. Their cost is not in agents.
unattributedCostUsdFloat!Provider cost of the unattributed calls in US dollars.
workspaceCostUsdFloat!attributedCostUsd + unattributedCostUsd: all model spend of the workspace in the window, for reconciling with apiUsageSummary.
workspaceCreditsApproxInt!Approximate credits for workspaceCostUsd.
isFloorBoolean!true when some calls carry no agent, so the per-agent figures are a floor of the workspace spend: show “at least”. Derived from the data, never from the setting.
attributionEnabledBoolean!Whether attribution is switched on right now. Informational: show “attribution not enabled yet” only when this is false and agents is empty.
from, untilDateTime!The window, from inclusive and until exclusive.

Each AgentCostDto has agentId, agentName (the placeholder removed when the agent has since been deleted; use the removed flag, not the text, to detect that), calls, failedCalls, inputTokens, outputTokens, costUsd (provider cost in US dollars) and creditsApprox. Credits are an approximation by the same blended conversion as creditsUsedThisMonthApprox in apiUsageSummary, not the per-model billing charge.

query {
tenantCostByAgent(window: MONTH_TO_DATE) {
attributionEnabled
isFloor
workspaceCostUsd
unattributedCostUsd
agents {
agentId
agentName
removed
calls
costUsd
}
}
}
workspaceModels: WorkspaceModelsDto!

Workspace owner only (a member who is not the owner gets FORBIDDEN). Read-only: which models this workspace may use, and the default an AI employee without its own model runs on. Changing the list is a Wetel staff action. It never returns prices, keys or endpoints; for prices see llmModelCatalog.

FieldTypeDescription
restrictedBoolean!true when the workspace is limited to a list of models; false means every platform model is allowed.
models[WorkspaceModelDto!]!The allowed models, ordered by provider then model id, at most 200.
totalModelsInt!The number of allowed models before that cap.
defaultModelIdString!The model an AI employee without its own model uses (the workspace setting, else the platform default).
defaultProviderLlmProviderTypeThe provider chain for that default. null only if the platform default is not a known chain.
defaultSourceWorkspaceModelDefaultSource!WORKSPACE_SETTING (set for this workspace by Wetel staff) or PLATFORM_DEFAULT.
defaultModelAllowedBoolean!false when the default model is itself outside the allowed list; calls on it are refused.

Each WorkspaceModelDto has modelId, provider (the chain that serves it), vendor (the model family, for example anthropic or google), supportsImages and isProviderDefault. The default model may be missing from models when the list is capped or the default is outside the allowlist.

query {
workspaceModels {
restricted
totalModels
defaultModelId
defaultSource
defaultModelAllowed
models {
modelId
provider
vendor
supportsImages
}
}
}

The signed-in user’s own recorded actions in their workspace: what they created, changed or deleted, newest first. You only ever see your own activity, and only inside your own tenant; there are no userId or tenantId arguments, both come from your token. A workspace owner can see the whole workspace with tenantAuditLogs.

Auth required: JWT (AuthJwtGuard).

Arguments:

ArgumentTypeNotes
firstIntPage size. Default 20, maximum 100.
afterStringThe endCursor of the previous page. A malformed cursor, or one from another query, returns 400.
auditableTypeStringOptional filter on the kind of item, for example Agent or Workflow.
actionAuditActionEnumOptional filter: CREATE, UPDATE or DELETE.

Returns: MyAuditLogConnection! (edges { cursor node }, pageInfo { hasNextPage endCursor }, totalCount).

Node fieldTypeNotes
idInt!
auditableTypeString!Agent, Workflow, ApiKey, CustomAction, McpConnector, ChannelConnector, KnowledgeBase, KnowledgeDocument, ScheduledWorkflow or Tenant (workspace settings).
auditableIdInt!The item’s own id.
actionAuditActionEnum!CREATE, UPDATE or DELETE. Revoking an API key is recorded as DELETE. Publishing a workflow is an UPDATE of its publish fields.
changedFields[String!]!The names of the fields in the request. Never values. Empty for create and delete.
createdAtDateTime!

What is recorded: creating, updating and deleting agents, API keys (create and revoke), workflows (including publish), custom actions, MCP connectors, scheduled workflows and knowledge bases; channel connector create, credential and settings changes, and activate or deactivate; knowledge document deletion; and workspace settings. Not recorded: sessions, messages, workflow runs and usage, knowledge document uploads and re-processing, and reads. Field names come from the request, not from a comparison with the stored value, so an update that sets a field to its current value is still listed. Entries are kept indefinitely.

Example request:

query MyActivity {
myAuditLogs(first: 20, auditableType: "Workflow") {
totalCount
pageInfo {
hasNextPage
endCursor
}
edges {
node {
id
auditableType
auditableId
action
changedFields
createdAt
}
}
}
}

Data-subject requests about one guest of your workspace, for the workspace owner only (anyone else gets FORBIDDEN). The guest is identified by the clientExternalId your integration gave their conversations. The workspace always comes from your sign-in, never from an argument.

exportGuestSubject(clientExternalId: String!) returns one JSON object with an array per category: sessions, messages, evaluations, workflowRuns, workflowTaskInvocations, approvals, artifacts (metadata only, no storage keys or download links). Unknown ids return empty arrays. Send the JSON to the requester yourself.

eraseGuestSubject(clientExternalId: String!, dryRun: Boolean!) deletes that guest’s conversations with their messages and evaluations, workflow runs and waits, task invocations, generated and exported files (rows and stored files) and channel mappings. Approval request text is blanked; the decision record is kept. dryRun is required with no default: true deletes nothing and returns counts, false deletes for good and cannot be undone. Run the dry run first.

mutation {
eraseGuestSubject(clientExternalId: "guest-123", dryRun: true) {
dryRun
storedFilesFailed
counts {
sessions
messages
workflowRuns
artifacts
storedFiles
approvalsCleared
}
}
}

Not erased: audit rows, billing and usage rows (no content), encrypted backups (they expire on their own schedule), and Telegram or partner message logs, which hold no guest key and are removed by their own 90-day schedule. If storedFilesFailed is above zero, some stored files could not be deleted after the rows were removed; contact support to have them removed. Each real erasure is audited with counts only; the guest id is never written down.

In production since 2026-10-30.

The audit trail of the whole workspace, for a security review. Workspace owner only (dashboard JWT): a member gets FORBIDDEN. The tenant comes from your token; there is no tenant argument.

tenantAuditLogs(first: Int = 20, after: String, since: DateTime, until: DateTime,
actorUserId: Int, resourceType: String, action: AuditActionEnum): TenantAuditLogConnection!
  • Paging. Newest first, Relay forward paging: first (default 20, maximum 100) and after (a previous pageInfo.endCursor, which walks to older rows; a malformed cursor is BAD_REQUEST). The connection has edges { cursor node } and pageInfo { hasNextPage endCursor }.
  • Filters (all combined): since and until (inclusive; since after until is BAD_REQUEST), actorUserId, resourceType (for example Workflow, at most 100 characters) and action.
  • Rate limit. 60 calls per minute per user.
  • Row fields (TenantAuditLogDto): id, createdAt, actorUserId (null for a system action or a sign-in attempt on an account), actorName (a snapshot at the time), resourceType, resourceId, action (CREATE, UPDATE or DELETE; many events are recorded as UPDATE), changedFields (field names only) and detail (set only for release decisions, for example state=APPROVED resourceType=AGENT).
  • Never included: values, secrets, tokens, password hashes, prompt text, message text or IP addresses.

What is audited: creating, changing, deleting and publishing agents and workflows; named API keys (create and revoke); custom actions and MCP connectors; channel connector create, credential, settings and activate or deactivate changes; knowledge base create and delete, and knowledge document delete; scheduled workflows (including pause and resume); workspace settings, tenant API key regeneration and the member-builder switch; release submit, approve, reject and revoke; approval decisions; member management (role changes, suspension, invites, password changes and resets, sign-out everywhere, two-factor changes) and sign-in attempts on accounts; guest data erasure; and audit exports.

What is not audited, so it is not here: reads of any kind, chat sessions and messages, workflow runs (including headless runs started with an API key), usage, exports other than the audit export, knowledge document uploads, workflow run cancellation, avatar, media and notification settings, and anything from before each of these was first recorded. A failed audit write is logged and skipped, so a row can be missing without the action failing. Rows are kept for 2 years once the retention rule for audit rows is switched on.

Ask for the same rows as a CSV file. The file is built in the background, so this is two steps.

mutation {
requestAuditLogExport(since: "2026-10-01T00:00:00Z") {
id
status
rowCap
}
}
query {
auditLogExport(id: 12) {
status
rowCount
truncated
downloadUrl
downloadUrlExpiresInSeconds
errorMessage
}
}
  • requestAuditLogExport takes the same optional filters as tenantAuditLogs and returns at once with status PENDING. Poll auditLogExport(id) until status is READY; FAILED carries a short, generic errorMessage (request a new export).
  • downloadUrl appears only while READY. It is valid for 15 minutes from each poll (a fresh link is made every time and never stored). Treat it like a credential: it opens the file without signing in.
  • 100,000 rows at most, newest first. When more rows matched, truncated is true and the file holds only the newest ones: narrow the filters (a shorter time range) and export again.
  • One export per workspace at a time (CONFLICT while one is pending), and 5 requests per hour per user. Any owner of the workspace can poll an export.
  • The file has the same columns and redaction as the query. A cell that starts with =, +, -, @, a tab or a carriage return is prefixed with a single quote so a spreadsheet does not run it as a formula.
  • The request is itself recorded in the audit trail (type AuditExport).

Workspaces can let members build and the owner release. It is off by default; an owner switches it on, and nothing changes for any workspace until they do.

setMemberBuilderForTenant(enabled: Boolean!) (workspace owner only) turns it on or off and returns the new value. myTenant { memberBuilder } says where it stands.

While it is on:

  • A member sees knowledge bases, custom actions, agents and workflows that are released (approved), that they created, or that have no recorded author (made before authorship was kept, or by a hire, treated as released). They can change or delete only their own that are not pending or approved. Anything else answers NOT_FOUND, the same as a missing id (an agent or workflow they may not see reads as null). agents and workflows list only what a member may see.
  • Agents a member creates start INACTIVE. The owner releases the agent and switches it on. A member cannot set an agent’s workflowId or its external sync fields (BAD_REQUEST), and cannot switch it on.
  • Workflows: a member can build and edit a draft and run draft tests, but can publish it (publishWorkflow, rollbackWorkflow) only once it is released. A pending or approved workflow, and any published one, cannot be edited by its author.
  • A member’s custom action cannot set credentials, extra headers or a per-call cost (bearerToken, credentialSecretHeaderName, larkAppId, larkAppSecret, larkRegion, credentialSource, extraHeaders, creditsPerCall): it answers BAD_REQUEST naming the fields. The owner adds those.
  • Publishing a workflow is refused while one of its LLM nodes points at a knowledge base, one of its ACTION nodes at a custom action, or one of its sub-agent nodes at an agent, that is not released (unless it has no recorded author). Owners are not exempt: a published workflow runs for everyone.
  • Who can use a released resource is set by its audience (below). By default a release is for every member. Using a resource at run time through the API (sessions, retrieval) is only partly gated: see the list of what an audience applies to.
  • Owners are never restricted.

A resource with no release is a draft. The release record is one row per resource:

CallWhoWhat
submitRelease(resourceType, resourceId)member (their own) or ownerSubmit a draft. A member’s becomes PENDING; an owner’s is APPROVED at once. CONFLICT if already pending or approved; a REJECTED or REVOKED one can be submitted again. resourceType is KNOWLEDGE_BASE, CUSTOM_ACTION, AGENT or WORKFLOW.
myReleasesany userYour own submissions, newest first, with the owner’s reason.
releasesByState(state)ownerEverything in a state (default PENDING), oldest first.
decideRelease(releaseId, approve, reason)ownerApprove or reject a PENDING release; a rejection needs a reason of at most 500 characters.
revokeRelease(releaseId, reason)ownerWithdraw an APPROVED release, with a reason.
withdrawRelease(releaseId: Int!)author or ownerTake back a release that is still PENDING, so the resource is a draft again and its author can edit and submit it afresh. Returns true. Anyone else, and an unknown id, gets NOT_FOUND; CONFLICT unless the release is PENDING (ask the owner to revoke an approved one). The owner is not notified of a withdrawal. Audited with ids only.
setReleaseAudience(releaseId, audience, userIds)ownerChange who may use an APPROVED release (below).
releaseVisibility(resourceType, resourceIds)any userWho may use each of up to 200 released resources, as you may see it (below).

knowledgeBases, customActions, agents and workflows also return createdByMe and releaseState on each item (null = a draft or a resource with no author), so a client can show Draft, Waiting, Released, Not approved or Withdrawn.

mutation {
submitRelease(resourceType: KNOWLEDGE_BASE, resourceId: 3) {
id
state
}
}
mutation {
decideRelease(releaseId: 9, approve: false, reason: "Add sources first") {
state
reason
}
}

The record (ResourceReleaseDto) has id, resourceType, resourceId, state (PENDING, APPROVED, REJECTED or REVOKED), audience (TENANT, SELECTED or TEST_GROUP; see below), audienceEnforced and audienceUserIds (owner only), submittedByUserId, decidedByUserId, decidedAt, reason, createdAt and updatedAt. Errors: NOT_FOUND for a resource a member did not create, or an unknown release id; CONFLICT for a release that is not in the state the call needs; FORBIDDEN for a member calling an owner-only operation.

Every release change is audited with the type and new state only, never the reason text.

setReleaseAudience(releaseId: ID!, audience: ReleaseAudience!, userIds: [Int!]) (workspace owner only) changes who may use an APPROVED release. audience is TENANT (every member, the default), SELECTED (only the colleagues in userIds, at least one) or TEST_GROUP (a private test: only the testers in userIds, which may be empty; the owner is always included). userIds must be active people of the workspace (at most 100) and replace the previous list; send none with TENANT. Revoking a release resets its audience to TENANT.

An audience is enforced only while the workspace has member-built drafts on; the result’s audienceEnforced says so (false means the audience is saved but nothing is hidden yet). When enforced, a signed-in dashboard member who is not included gets NOT_FOUND, null or an empty list (and FORBIDDEN, or a stream that ends, on a subscription) for: the lists and reads of knowledge bases, custom actions, agents and workflows; starting a session on the agent; everything reached through the agent (its sessions and messages, runs, evaluations, sessionEvents, artifacts, schedules, Office reads and channel connectors); testCustomAction; and attaching a knowledge base to a Free Chat. Publishing a workflow refuses any knowledge base, custom action or sub-agent that is not set to TENANT, owners included. While the flag is on, only the owner can create an API key, because a key carries no signed-in user and so can never be narrowed. Open subscriptions re-check the viewer about every 60 seconds.

releaseVisibility(resourceType: ReleaseResourceType!, resourceIds: [Int!]!) returns one ReleaseVisibilityDto per APPROVED release among at most 200 ids (BAD_REQUEST above that): resourceType, resourceId, audience, enforced, and for the owner only releaseId and audienceUserIds (a member never learns who else is on a list). A member sees a row only for a release that is for everyone or includes them. Use it to show a “Visible to” label.


For creating and configuring the agents that live inside a tenant, see Agents. For the full signup-to-first-agent walkthrough, see Getting Started.