# 自建应用获取 tenant_access_token
OAuth 令牌接口，用于获取 <code>tenant_access_token</code>。<code>tenant_access_token</code> 为应用访问凭证，使用该凭证可以以应用身份调用 OpenAPI。
**注意事项**：**此版本的 <code>tenant_access_token</code> 使用 JWT 格式，凭证长度相比旧版显著增加。**升级前请检查数据库字段、缓存、序列化、反向代理以及 HTTP Header 等存储和传输链路的长度限制。不要按照旧版凭证的固定长度进行存储，建议至少预留 4 KB。

- 本接口遵循 OAuth 2.0 Client Credentials Grant，请求中的 `grant_type` 固定为 `client_credentials`。
- 新版接口在响应体的 `access_token` 字段中返回 `tenant_access_token`，请勿继续从旧版字段 `tenant_access_token` 中读取凭证。
- `tenant_access_token` 的有效期最长为 2 小时。建议在服务端缓存并复用凭证，在凭证即将过期时重新获取，避免每次调用 OpenAPI 前都请求本接口。凭证的实际有效期请以接口响应中返回的 `expires_in` 为准，请勿硬编码固定的有效期，建议根据 `expires_in` 在凭证过期前重新调用本接口获取新的凭证。
- 自建应用的目标租户由应用自身确定，无需传入 `tenant_key`，且不能使用本接口获取其他租户的凭证。
- App Secret 属于敏感信息，只能保存在应用服务端，请勿将其写入前端代码、客户端安装包或日志。
**注意事项**：本接口实现遵循 [RFC 6749 - The OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749) ，你可以使用[标准的 OAuth 客户端库](https://oauth.net/code/)进行接入（**推荐**）
**注意事项**：**本接口支持两种客户端认证方式：**
1. <code>client_secret_basic</code>：HTTP Basic Auth 认证，参考 [RFC 7617](https://datatracker.ietf.org/doc/html/rfc7617)
2. <code>client_secret_post</code>：在请求体参数中携带 <code>client_secret</code> 进行认证

单次请求只能使用其中一种认证方式，否则接口将返回错误码 20070。

## 请求

基本 | &nbsp;
---|---
HTTP URL | https://accounts.feishu.cn/oauth/v3/token
HTTP Method | POST
接口频率限制 | [1000 次/分钟、50 次/秒](https://open.feishu.cn/document/ukTMukTMukTM/uUzN04SN3QjL1cDN)
支持的应用类型 | Custom App
权限要求<br>**调用该 API 所需的权限。开启其中任意一项权限即可调用<br>** | 无

### 请求头

名称 | 类型 | 必填 | 描述
---|---|---|---
Content-Type | string | 是 | 请求体类型。推荐使用 `application/x-www-form-urlencoded`，同时兼容 `application/json`。

### 请求体

名称 | 类型 | 必填 | 描述
---|---|---|---
grant_type | string | 是 | 授权类型。<br>**固定值：**`client_credentials`
client_id | string | 否 | 应用的 App ID。使用 `client_secret_basic` 认证方式时从 Authorization 请求头中获取，无需传入；其他认证方式必填。应用凭证 App ID 和 App Secret 获取方式：<br>1. 登录[飞书开发者后台](https://open.feishu.cn/app)。<br>2. 进入应用详情页，在左侧导航栏，单击 **凭证与基础信息**。<br>3. 在 **应用凭证** 区域，获取并保存 **App ID** 和 **App Secret**。<br>**示例值：**`cli_a5ca35a685b0x26e`
client_secret | string | 否 | 应用的 App Secret。使用 `client_secret_post` 认证方式时必填；使用 `client_secret_basic` 认证方式时不要传入。应用凭证 App ID 和 App Secret 获取方式：<br>1. 登录[飞书开发者后台](https://open.feishu.cn/app)。<br>2. 进入应用详情页，在左侧导航栏，单击 **凭证与基础信息**。<br>3. 在 **应用凭证** 区域，获取并保存 **App ID** 和 **App Secret**。<br>**示例值：**`baBqE5um9LbFGDy3X7LcfxQX1sqpXlwy`
scope | string | 否 | 申请写入本次 `tenant_access_token` 的应用身份权限列表。<br>**注意：**<br>- 只能传入应用已开通且支持应用身份调用的权限，否则接口将返回错误码 20068。<br>- 不能传入重复的权限，否则接口将返回错误码 20067。<br>- 未传入或传入空值时，默认使用应用在目标租户下已开通的应用身份权限。响应中的 `scope` 表示本次 token 最终生效的权限列表；若最终权限列表为空，则不返回 `scope` 字段。<br>**格式要求：** 以空格分隔的 `scope` 列表<br>**示例值：**`im:message:send_as_bot im:message.urgent:app_send`

### 请求体示例

使用 App Secret 示例：

```json
{
    "grant_type": "client_credentials",
    "client_id": "cli_a5ca35a685b0x26e",
    "client_secret": "baBqE5um9LbFGDy3X7LcfxQX1sqpXlwy",
    "scope": "im:message:send_as_bot im:message.urgent:app_send"
}
```

## 响应

响应体类型为 `application/json; charset=utf-8`。

### 响应体

名称 | 类型 | 描述
---|---|---
code | int | 错误码，为 0 时表明请求成功，非 0 表示失败，请参照下文[错误码](#错误码)一节进行相应处理
access_token | string | 即 `tenant_access_token`，仅在请求成功时返回。调用 OpenAPI 时，在请求头中以 `Authorization: Bearer access_token` 的格式传入
expires_in | int | 即 `tenant_access_token` 的有效期，单位为秒，仅在请求成功时返回<br>**注意事项**：建议使用该字段确定 `tenant_access_token` 的过期时间，不要硬编码有效期，实际有效期以接口返回的 `expires_in` 为准
token_type | string | 值固定为 `Bearer`，仅在请求成功时返回
scope | string | 本次 `tenant_access_token` 最终生效的应用身份权限列表，以空格分隔。仅在请求成功且最终生效的权限列表非空时返回；若最终权限列表为空，则不返回该字段
error | string | 错误类型，仅在请求失败时返回
error_description | string | 具体的错误信息，仅在请求失败时返回

### 响应体示例

成功响应示例：

```json
{
    "code": 0,
    "access_token": "eyJhbGciOiJFUzI1NiIs**********X6wrZHYKDxJkWwhdkrYg",
    "expires_in": 7200,
    "scope": "im:message:send_as_bot im:message.urgent:app_send",
    "token_type": "Bearer"
}
```

失败响应示例：

```json
{
    "code": 20050,
    "error": "server_error",
    "error_description": "An unexpected server error occurred. Please retry your request."
}
```

### 错误码

HTTP 状态码 | 错误码 | 描述 | 排查建议
---|---|---|---
400 | 20001 | The request is malformed. Please check your request. | 请求格式或参数不合法，请检查请求体格式和参数类型
400 | 20002 | The client secret is invalid. | 应用认证失败，请检查提供的 `client_id` 与 `client_secret` 是否正确；如果刚重置过 App Secret，请使用新值
400 | 20009 | The specified app is not installed. | 租户未安装应用，请检查应用状态
400 | 20036 | The specified grant_type is not supported. | 无效的 `grant_type`，请将请求体中的 `grant_type` 设置为 `client_credentials`
400 | 20048 | The specified app does not exist. | 应用不存在，请检查 `client_id` 是否来自当前应用且格式正确，并确认应用状态
500 | 20050 | An unexpected server error occurred. Please retry your request. | 内部服务错误，请稍后重试，如果持续报错请联系[技术支持](https://applink.feishu.cn/TLJpeNdW)
400 | 20063 | The request is missing a required parameter. | 请求中缺少必要字段，请根据 `error_description` 补充 `grant_type`、`client_id` 或 `client_secret`
400 | 20067 | The provided scope list contains duplicate scopes. Please ensure all scopes are unique. | 无效的 `scope` 列表，其中存在重复项，请去重后重新请求
400 | 20068 | The provided scope list contains scopes that are not permitted. Please ensure all scopes are allowed. | 无效的 `scope` 列表。请确认应用已开通对应的应用身份权限，且该权限支持应用身份调用
400 | 20069 | The specified app is not enabled. | 应用未启用，请确认应用版本已发布，并由企业管理员启用应用
400 | 20070 | Multiple authentication methods were provided. Please only use one to proceed. | 请求中同时使用了 <code>client_secret_basic</code> 和 <code>client_secret_post</code>。请仅使用其中一种身份认证方式调用本接口
400 | 20130 | The client authentication failed. | 客户端认证失败，请检查应用启用的认证方式，以及 App ID 和 App Secret 是否正确
400 | 20140 | The auth method is not supported. | 当前应用不支持所使用的客户端认证方式，请在开发者后台检查并启用对应认证方式，或改用应用已启用的方式

