Personal Access Tokens
A personal access token (PAT) lets a script, the DocsGPT CLI or a CI/CD pipeline act on your account without a browser session. Unlike an agent API key, which can only talk to one agent, a PAT manages resources: it can create and update agents, upload sources, edit prompts and tools, and run agents for benchmarking.
Every token is limited in three ways:
- Scopes decide which parts of the API the token may call.
- Resource restrictions (optional) narrow a token to specific agents, sources, prompts, tools or workflows.
- Expiry ends the token’s life automatically.
Creating a token
- Open Settings → Access Tokens in the DocsGPT web app.
- Choose Create token, give it a name, and select the scopes it needs.
- Optionally restrict it to specific resources and pick an expiry.
- Copy the token. It starts with
dgpt_pat_and is shown once. DocsGPT stores only a hash of it, so a lost token cannot be recovered. Revoke it and create a new one.
Tokens can only be created, regenerated and revoked from a signed-in session. A token cannot create, list, regenerate or revoke tokens, so a leaked token cannot mint a replacement for itself.
Using a token
Send the token as a bearer credential:
export DOCSGPT_URL=https://docsgpt.example.com
export DOCSGPT_TOKEN=dgpt_pat_...
curl -H "Authorization: Bearer $DOCSGPT_TOKEN" "$DOCSGPT_URL/api/user/me"GET /api/user/me works with any valid token and reports what the token may do, which makes it a convenient first step in a pipeline:
{
"success": true,
"user_id": "alice@example.com",
"roles": ["user"],
"auth_method": "pat",
"token": {
"id": "0b6c...",
"name": "ci-deploy",
"scopes": ["agents:read", "agents:write"],
"resource_filter": {}
}
}Applying agent definitions
Agents can be exported to YAML and applied back, which makes them reviewable and deployable like any other configuration. With the CLI:
docsgpt-cli agents export <agent-id> -o support-bot.agent.yaml
docsgpt-cli agents apply -f support-bot.agent.yaml --dry-run
docsgpt-cli agents apply -f support-bot.agent.yamlOr with the API directly (agents:write):
curl -X POST "$DOCSGPT_URL/api/import_agent/plan" \
-H "Authorization: Bearer $DOCSGPT_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -Rs '{yaml: .}' support-bot.agent.yaml)"Sources are matched by name, and when several of your sources share a name the oldest one wins. A pipeline that re-uploads documentation on every push should therefore upload with docsgpt-cli sources upload ... --wait --replace (which removes the older same-named sources) and run agents apply afterwards, or the agent stays bound to the first upload.
/api/import_agent/plan is a dry run that reports whether the agent would be created or updated and how each referenced source, tool and prompt resolves. /api/import_agent applies it. An agent is matched by metadata.id, then metadata.slug; when nothing matches, a new draft agent is created.
GitHub Actions example
jobs:
deploy-agents:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Apply agent definitions
env:
DOCSGPT_URL: ${{ vars.DOCSGPT_URL }}
DOCSGPT_TOKEN: ${{ secrets.DOCSGPT_TOKEN }}
run: |
docsgpt-cli sources upload docs/*.md --name "Product docs" --wait --replace --idempotency-key "docs-${{ github.sha }}"
docsgpt-cli agents apply -f agents/Scopes
A write scope includes the matching read scope.
| Scope | Allows |
|---|---|
agents:read | View agents, folders, guardrail events and export agent definitions |
agents:write | Create, update, delete, share and import (apply) agents and folders |
agents:keys | Regenerate agent API keys and read incoming webhook URLs |
sources:read | View sources, their files, chunks and ingestion task status |
sources:write | Upload, ingest, sync, edit and delete sources and chunks |
prompts:read / prompts:write | View / create, update and delete prompts |
tools:read / tools:write | View / create, update and delete tools and MCP servers |
models:read / models:write | View models / manage custom models |
workflows:read / workflows:write | View / create, update and delete workflows |
schedules:read / schedules:write | View / create, update, run and delete agent schedules |
conversations:read / conversations:write | View / rename, delete and rate conversations |
analytics:read | View usage analytics and logs |
teams:read | View teams, members and resource shares |
chat:run | Ask agents and search sources (/api/answer, /stream, /api/search); used for benchmarking |
agents:keys is separate from agents:write on purpose. Creating, publishing or adopting an agent mints its API key; a token without agents:keys gets the key back masked (1234...90ab), because an agent key keeps working after the token that saw it is revoked. Put differently: a deployment token that updates agents does not need to be able to read or rotate the secrets other systems use to call them.
Some parts of the API are never available to a token, whatever its scopes: token management, the admin API, team management, sign-in flows, device pairing, and the interactive OAuth handshakes used by connectors and MCP servers. A token also never carries the admin role, even when its owner is an admin.
Authorization is deny by default. An endpoint that is not explicitly mapped to a scope cannot be called with a token, and answers 403 with "error": "not_available_to_tokens". A mapped endpoint called without the scope answers 403 with "error": "insufficient_scope" and names the required_scope.
Resource restrictions
A token can be narrowed to specific resources in any of these families: agents, sources, prompts, tools, workflows. A family that is not listed stays unrestricted within the token’s scopes.
{
"name": "support-bot-deploy",
"scopes": ["agents:write", "chat:run"],
"resource_filter": { "agents": ["3f0e8f0c-5a53-4f0e-9a39-0e5f4f8d2c11"] },
"expires_in_days": 30
}For a restricted family the token:
- can read, update and delete only the listed resources, and listings show only those;
- cannot create new resources of that family, since a new resource would be outside the list;
- cannot attach a resource outside the list to something else, for example set an agent’s source to a source the token may not use;
- is refused (
403,"error": "resource_not_allowed") wherever DocsGPT cannot prove the request stays inside the list:- Conversations, analytics and message replay (
/api/messages/<id>/tail,/api/messages/<id>/events) are closed to every restricted token. They span all agents and contain cited source text and tool output. - Schedules run an agent with a free-form instruction and store the output. A token restricted to agents can list and create schedules for its agents; every other schedule route, and schedules altogether for tokens restricted on another family, are closed.
- Workflow writes are closed to tokens restricted on sources, tools or prompts, because a workflow graph names those inside its nodes. Such a token also cannot attach a workflow to an agent unless it is restricted on workflows too, in which case only the listed workflows can be attached.
/api/sources/paginatedis closed to source-restricted tokens (use/api/sources).
- Conversations, analytics and message replay (
A restriction covers what the token asks for, not what an allowed resource already contains: an agent on the list runs with its own sources, prompt and tools even when the token is also restricted on those families. List an agent only if you are happy for the token to use everything that agent uses.
Restrictions and chat (chat:run):
- A token restricted to specific agents must pass exactly one
agent_idin the request body, and it must be one of the listed agents. An agentapi_keyor an inline workflow in the body is refused. - A token restricted to specific sources only may chat against those sources with
active_docs. It cannot run agents, because an agent brings its own sources. Restrict the token to agents instead to allow that. - A token restricted on prompts or workflows must also be restricted to agents to chat.
- A token restricted on tools cannot use chat at all, and a tools restriction cannot be combined with
chat:runwhen the token is created. Chat executes tools (an agent’s own, or your default tools when there is no agent) and those cannot be held to a list. - A
conversation_idmust belong to the agent being run (or to no agent, for agent-less chat). Otherwise the server would continue, append to, or resume pending tool calls of another agent’s conversation.
agents:write and import: applying an agent definition can create the prompt and tools it references and rewrite the agent’s workflow, all under agents:write alone. It does not need prompts:write, tools:write or workflows:write, so treat agents:write as able to create those through an import.
Restrictions and agents apply: a token restricted to specific agents can apply a definition only when it updates one of those agents. A token restricted on sources, prompts, tools or workflows cannot import agents at all, because an import resolves those references by name and may create them.
Expiry and revocation
- A token created without an explicit lifetime expires after
PAT_DEFAULT_LIFETIME_DAYS(90 by default). Users can choose any lifetime up toPAT_MAX_LIFETIME_DAYS(365 by default). - Non-expiring tokens are available only when the operator sets
PAT_ALLOW_NON_EXPIRING=true. - Regenerate in Settings → Access Tokens issues a new secret for the same token and resets its expiry. The name, scopes and restrictions stay; the old secret stops working immediately, so update whatever uses it. The new lifetime defaults to the one the token was last issued with, and an expired token can be renewed this way (a revoked one cannot). This is the way to rotate a secret or extend a token without rebuilding its scopes.
- Revoking a token in Settings → Access Tokens takes effect on the next request.
- Admins can list a user’s tokens with
GET /api/admin/users/<user_id>/tokensand revoke any token withDELETE /api/admin/tokens/<token_id>. The admin revoke sessions action also revokes all of that user’s tokens. - Tokens of a deactivated user (through the admin API or SCIM) stop working immediately and work again if the user is reactivated.
GET /api/user/tokensreports a token past its expiry as"status": "expired".- Token creation and revocation are recorded in the authentication audit log (
pat_created,pat_regenerated,pat_revoked), visible to admins.
An expired token’s name can be reused: creating a token with that name retires the expired one.
Each user may hold up to PAT_MAX_PER_USER live tokens (25 by default). The token list shows when and from which IP address each token was last used.
Operator settings
| Setting | Default | Purpose |
|---|---|---|
PAT_ENABLED | true | Master switch. When false, tokens cannot be created and every existing token stops authenticating immediately |
PAT_DEFAULT_LIFETIME_DAYS | 90 | Lifetime of a token created without an explicit expiry |
PAT_MAX_LIFETIME_DAYS | 365 | Longest lifetime a user may request |
PAT_ALLOW_NON_EXPIRING | false | Let users create tokens that never expire |
PAT_MAX_PER_USER | 25 | Maximum number of live tokens per user |
Personal access tokens need a stable user identity, so they are available with AUTH_TYPE=oidc and with authentication disabled (single-user self-hosting). They are not available with simple_jwt or session_jwt.
Turning PAT_ENABLED off, or switching AUTH_TYPE to simple_jwt or session_jwt, is not limited to the settings page: every pipeline that uses a token starts getting 401 right away. Tokens are not deleted and work again once the setting is restored. See the Settings Reference for details.
Management API
These endpoints need a signed-in session and cannot be called with a token.
| Endpoint | Purpose |
|---|---|
GET /api/user/tokens | List your tokens, the scope catalog and the server’s token policy |
POST /api/user/tokens | Create a token. Body: name, scopes, optional resource_filter, optional expires_in_days (0 = never, when allowed). The response carries the plaintext token once |
POST /api/user/tokens/<id>/regenerate | New secret and new expiry for the same token. Optional body expires_in_days; omitted = the lifetime it was last issued with. The response carries the plaintext token once |
DELETE /api/user/tokens/<id> | Revoke a token |
Good practice
- Give each pipeline its own token with the narrowest scopes that work, and name it after where it is used.
- Store tokens in your CI system’s secret store. Never commit them. The
dgpt_pat_prefix lets secret scanners recognise them. - Prefer short lifetimes for tokens used by automation you can easily re-provision.
- Revoke a token as soon as it is no longer needed or may have been exposed.