> This page is for version v1.
> For other versions, use one of these documentation indexes:
> - v2 (default): https://autodesk-poc.ferndocs.com/v2/llms.txt
> - v1: https://autodesk-poc.ferndocs.com/v1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://autodesk-poc.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://autodesk-poc.ferndocs.com/_mcp/server.

# Authentication

Every request carries an APS OAuth token in the `Authorization` header. Which
token is acceptable depends on the operation: read operations generally take any
token, while write operations act on behalf of a user and therefore reject a
plain app-only token.

| Flow                        | Token represents                              | Accepted by               |
| --------------------------- | --------------------------------------------- | ------------------------- |
| 2-legged                    | Your app                                      | Most read operations      |
| 2-legged with impersonation | Your app, acting as a user (`User-Id` header) | Read and write operations |
| 3-legged                    | The signed-in user                            | Read and write operations |

The scopes are the same in all three flows: `account:read` for reads,
`account:write` for writes, and `data:read` where user data is returned. The
required scope is listed on each operation page.

## 2-legged (client credentials)

#### Exchange your client credentials for a token

Call [Get a 2-legged access token](/v1/acc-admin/authentication/get-token) with
`grant_type=client_credentials` and the scopes you need. Client
authentication goes either in the body or in an
`Authorization: Basic base64(client_id:client_secret)` header — sending both
returns `400`.

#### Call the API

Send the token as `Authorization: Bearer <access_token>`. Tokens are valid
for the number of seconds in `expires_in`; cache and reuse them rather than
minting one per request.

## 2-legged with user impersonation

Same token as above, plus a `User-Id` header holding the ACC user ID (or the
Autodesk ID) of the user the call acts as. That user must have permission to
perform the operation in the hub or project.

**`Add a project user as an impersonated hub admin`**

```bash title="Add a project user as an impersonated hub admin"
curl -X POST "https://developer.api.autodesk.com/construction/admin/v1/projects/$PROJECT_ID/users" \
  -H "Authorization: Bearer $TOKEN" \
  -H "User-Id: $ACC_USER_ID" \
  -H "Content-Type: application/json" \
  -d '{"email":"member@example.com","products":[{"key":"projectAdministration","access":"administrator"}]}'
```

> **Warning**
>
> Operations that create or modify data — `POST accounts/:accountId/projects`,
> `PATCH projects/:projectId`, all project-user writes, and the lifecycle
> operations — accept **only** 2-legged with impersonation or 3-legged tokens. A
> plain 2-legged token returns `403`.

## 3-legged (authorization code)

Send the user through `GET /authentication/v2/authorize`, then exchange the
returned code at the token endpoint. The resulting token already carries the
user's identity, so no `User-Id` header is needed. The authorize step is a
browser redirect and is therefore not part of the API reference or the
playground.

> **Note**
>
> The API playground on each operation page mints a 2-legged token for you from
> a client ID and secret. To try an impersonated call, add the `User-Id` header
> in the playground's header section.