---
title: "Authentication — GanttFather API"
description: "Bearer tokens, scopes, permissions, and how authorization behaves on the wire."
canonical: "https://ganttfather.com/docs/api/authentication/"
locale: "en"
category: "product"
---

# Authentication — GanttFather API

API reference [AI assistants (MCP)](https://ganttfather.com/docs/ai-agent/)

## Getting started

- [Introduction](https://ganttfather.com/docs/api/introduction/)
- [Authentication](https://ganttfather.com/docs/api/authentication/)
- [Pagination](https://ganttfather.com/docs/api/pagination/)
- [Rate limits & quotas](https://ganttfather.com/docs/api/rate-limits/)
- [Errors](https://ganttfather.com/docs/api/errors/)

## Projects

- [GET List projects](https://ganttfather.com/docs/api/list-projects/)
- [GET Get project](https://ganttfather.com/docs/api/get-project/)

## Tasks

- [GET List tasks](https://ganttfather.com/docs/api/list-tasks/)
- [GET Get task](https://ganttfather.com/docs/api/get-task/)
- [POST Create task](https://ganttfather.com/docs/api/create-task/)
- [PATCH Update task](https://ganttfather.com/docs/api/update-task/)
- [DELETE Delete task](https://ganttfather.com/docs/api/delete-task/)
- [POST Reorder tasks](https://ganttfather.com/docs/api/reorder-tasks/)
- [PUT Set assignees](https://ganttfather.com/docs/api/set-assignees/)

## Dependencies

- [GET List dependencies](https://ganttfather.com/docs/api/list-dependencies/)
- [PUT Set dependencies](https://ganttfather.com/docs/api/set-dependencies/)
- [POST Add dependency](https://ganttfather.com/docs/api/add-dependency/)
- [DELETE Remove dependency](https://ganttfather.com/docs/api/remove-dependency/)

## Resources

- [GET List resources](https://ganttfather.com/docs/api/list-resources/)
- [POST Create resource](https://ganttfather.com/docs/api/create-resource/)
- [PATCH Update resource](https://ganttfather.com/docs/api/update-resource/)
- [DELETE Delete resource](https://ganttfather.com/docs/api/delete-resource/)

## Members

- [GET List members](https://ganttfather.com/docs/api/list-members/)

 Getting started / **Authentication**

# Authentication

 Updated Jul 4, 2026

 Every request carries your token as a Bearer header:

 Authorization: Bearer glt_YOUR_TOKEN
 Tokens are created in **Settings → AI Agents & API**. Copy the glt_… value once — only its hash is stored, so it can’t be shown again. Revoking a token cuts off access instantly, and each token tracks when it was last used.

## Scopes

 Scope Reads Writes

 **Project token** the granted project set the granted project set

 **Account token** any project you’re a member of (or own) — pass projectId explicitly any project where **you** are an editor

 An Account token acts *as you*: it can never do more than your own role allows. If you’re a view-only guest on a project, a ReadWrite token still can’t write there — writes are attributed to your membership, and API-created tasks are assigned to the token’s own integration identity on the project roster.

## Permissions

 Each token is **ReadOnly** or **ReadWrite**. ReadOnly tokens can call every GET; any write returns 403 forbidden — uniformly, whether the target exists or not.

## How denials behave (by design)

- **Wrong or revoked token** → 401 with a Bearer challenge. An expired token, a revoked token, and a token whose account was deactivated are indistinguishable.

- **A resource you can’t reach, addressed by its own id** ( GET / PATCH / DELETE on /tasks/{id} , /resources/{id} , /projects/{id} and their sub-paths) → 404 , never 403 . A foreign id looks exactly like a nonexistent one — the API never confirms existence of things you can’t access. Archived (soft-deleted) projects behave as nonexistent too, including their tasks, members, and resources.

- **A project you name in the URL to write into** ( POST /projects/{id}/tasks , .../tasks/reorder , .../resources ) that you cannot write to → 403 forbidden . Because you supplied the project id, a 403 here reveals nothing you didn’t already assert; a foreign and a nonexistent project both answer the same 403 (no existence oracle).

- **A project you CAN reach but that is read-only** (subscription lapsed, admin lock, pending deletion) → 403 with code project_read_only and the reason in the message.

- **A ReadOnly token attempting any write** → 403 forbidden .

## User-Agent

 Every request must include a non-empty User-Agent header identifying your client. A request without one is rejected before your token is even checked, with 403 and:

 { "code" : "user_agent_required" }

 Note that curl, browsers, and standard HTTP libraries (in most languages) send a User-Agent automatically — you’ll only hit this if you’re building a raw request by hand. In that case, set one explicitly:

 User-Agent: my-app/1.0

## HTTPS only

 Plain-HTTP requests never reach the API. Keep tokens out of URLs and logs; send them only in the Authorization header.
