Skip to main content

Use cases

This API gets the user’s accessToken and is a key step in implementing user identity authentication. Common use cases include:
  • After a user signs in, exchange the authorization code (code) for a valid access credential.
  • Before the accessToken expires, use the refreshToken to renew it automatically and avoid frequent re-authorization.
  • A third-party enterprise app integrates with the DingTalk unified sign-in system to implement single sign-on (SSO).
  • An enterprise app calls protected APIs on behalf of a user from its backend service.
Developers should properly manage the lifecycle of the accessToken. We recommend caching it locally and setting up an automatic refresh mechanism to ensure stable API calls.
When using the access token, note the following:
  • The accessToken is valid for 7,200 seconds (2 hours). Repeated requests within the validity period return the same result and automatically renew it. After expiration, a new accessToken is returned.
  • Each app’s accessToken is independent. Cache the token by app to avoid confusion.

Request

Basic information
HTTP URLhttps://api.dingtalk.io/v1.0/oauth2/userAccessToken
HTTP MethodPOST
Supported app typesappType-Internal app appType-Third-party enterprise app appType-Third-party personal app
Required permissionspermission-open_app_api_base-Basic permission to obtain user access credentials for DingTalk Open APIs

Request body

NameTypeRequiredExampleDescription
clientIdStringYesdingxxxApp ID. You can use the AppId of the Scan QR Code sign-in app or the third-party personal mini program. - For an internal app, pass the app’s AppKey. - For a third-party enterprise app, pass the app’s SuiteKey. - For a third-party personal app, pass the app’s AppId.
clientSecretStringYes1234App secret. - For an internal app, pass the app’s AppSecret. - For a third-party enterprise app, pass the app’s SuiteSecret. - For a third-party personal app, pass the app’s AppSecret.
codeStringNoabcdOAuth 2.0 temporary authorization code. Third-party enterprise apps must integrate with the unified authorization suite or Get the access credential of the signed-in user to get the temporary authorization code authCode.
refreshTokenStringNoabcdOAuth 2.0 refresh token, obtained from the previous API response. It is valid for 30 days.
grantTypeStringYesauthorization_code- To exchange an authorization code for a token, pass authorization_code. In this case, the code parameter is required. - To exchange a refresh token for a new token, pass refresh_token. In this case, the refreshToken parameter is required.

Request example

curl -X POST 'https://api.dingtalk.io/v1.0/oauth2/userAccessToken' \
  -H 'Content-Type: application/json' \
  -d '{
    "clientId": "dingxxx",
    "clientSecret": "1234",
    "code": "abcd",
    "refreshToken": "abcd",
    "grantType": "authorization_code"
  }'
Java
// This file is auto-generated, don't edit it. Thanks.
package com.aliyun.sample;

import com.aliyun.tea.*;
import com.aliyun.teautil.*;
import com.aliyun.dingtalkoauth2_1_0.*;
import com.aliyun.dingtalkoauth2_1_0.models.*;
import com.aliyun.teaopenapi.*;
import com.aliyun.teaopenapi.models.*;

public class Sample {

    /**
     * Initialize the account Client using a Token
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dingtalkoauth2_1_0.Client createClient() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkoauth2_1_0.Client(config);
    }

    public static void main(String[] args_) throws Exception {
        java.util.List<String> args = java.util.Arrays.asList(args_);
        com.aliyun.dingtalkoauth2_1_0.Client client = Sample.createClient();
        GetUserTokenRequest getUserTokenRequest = new GetUserTokenRequest()
                .setClientId("dingxxx")
                .setClientSecret("1234")
                .setCode("abcd")
                .setRefreshToken("abcd")
                .setGrantType("authorization_code");
        try {
            client.getUserToken(getUserTokenRequest);
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err contains the code and message properties, which help locate the issue
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err contains the code and message properties, which help locate the issue
            }

        }        
    }
}
Python
# -*- coding: utf-8 -*-
# This file is auto-generated, don't edit it. Thanks.
import sys

from typing import List

from alibabacloud_dingtalk.oauth2_1_0.client import Client as dingtalkoauth2_1_0Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_dingtalk.oauth2_1_0 import models as dingtalkoauth_2__1__0_models
from alibabacloud_tea_util.client import Client as UtilClient

class Sample:
    def __init__(self):
        pass

    @staticmethod
    def create_client() -> dingtalkoauth2_1_0Client:
        """
        Initialize the account Client using a Token
        @return: Client
        @throws Exception
        """
        config = open_api_models.Config()
        config.protocol = 'https'
        config.region_id = 'central'
        return dingtalkoauth2_1_0Client(config)

    @staticmethod
    def main(
        args: List[str],
    ) -> None:
        client = Sample.create_client()
        get_user_token_request = dingtalkoauth_2__1__0_models.GetUserTokenRequest(
            client_id='dingxxx',
            client_secret='1234',
            code='abcd',
            refresh_token='abcd',
            grant_type='authorization_code'
        )
        try:
            client.get_user_token(get_user_token_request)
        except Exception as err:
            if not UtilClient.empty(err.code) and not UtilClient.empty(err.message):
                # err contains the code and message properties, which help locate the issue
                pass

    @staticmethod
    async def main_async(
        args: List[str],
    ) -> None:
        client = Sample.create_client()
        get_user_token_request = dingtalkoauth_2__1__0_models.GetUserTokenRequest(
            client_id='dingxxx',
            client_secret='1234',
            code='abcd',
            refresh_token='abcd',
            grant_type='authorization_code'
        )
        try:
            await client.get_user_token_async(get_user_token_request)
        except Exception as err:
            if not UtilClient.empty(err.code) and not UtilClient.empty(err.message):
                # err contains the code and message properties, which help locate the issue
                pass

if __name__ == '__main__':
    Sample.main(sys.argv[1:])
PHP
<?php

// This file is auto-generated, don't edit it. Thanks.
namespace AlibabaCloud\SDK\Sample;

use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Dingtalk;
use \Exception;
use AlibabaCloud\Tea\Exception\TeaError;
use AlibabaCloud\Tea\Utils\Utils;

use Darabonba\OpenApi\Models\Config;
use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Models\GetUserTokenRequest;

class Sample {

    /**
     * Initialize the account Client using a Token
     * @return Dingtalk Client
     */
    public static function createClient(){
        $config = new Config([]);
        $config->protocol = "https";
        $config->regionId = "central";
        return new Dingtalk($config);
    }

    /**
     * @param string[] $args
     * @return void
     */
    public static function main($args){
        $client = self::createClient();
        $getUserTokenRequest = new GetUserTokenRequest([
            "clientId" => "dingxxx",
            "clientSecret" => "1234",
            "code" => "abcd",
            "refreshToken" => "abcd",
            "grantType" => "authorization_code"
        ]);
        try {
            $client->getUserToken($getUserTokenRequest);
        }
        catch (Exception $err) {
            if (!($err instanceof TeaError)) {
                $err = new TeaError([], $err->getMessage(), $err->getCode(), $err);
            }
            if (!Utils::empty_($err->code) && !Utils::empty_($err->message)) {
                // err contains the code and message properties, which help locate the issue
            }
        }
    }
}
$path = __DIR__ . \DIRECTORY_SEPARATOR . '..' . \DIRECTORY_SEPARATOR . 'vendor' . \DIRECTORY_SEPARATOR . 'autoload.php';
if (file_exists($path)) {
    require_once $path;
}
Sample::main(array_slice($argv, 1));
Go
// This file is auto-generated, don't edit it. Thanks.
package main

import (
  "os"
  util  "github.com/alibabacloud-go/tea-utils/service"
  dingtalkoauth2_1_0  "github.com/alibabacloud-go/dingtalk/oauth2_1_0"
  openapi  "github.com/alibabacloud-go/darabonba-openapi/client"
  "github.com/alibabacloud-go/tea/tea"
)

/**
 * Initialize the account Client using a Token
 * @return Client
 * @throws Exception
 */
func CreateClient () (_result *dingtalkoauth2_1_0.Client, _err error) {
  config := &openapi.Config{}
  config.Protocol = tea.String("https")
  config.RegionId = tea.String("central")
  _result = &dingtalkoauth2_1_0.Client{}
  _result, _err = dingtalkoauth2_1_0.NewClient(config)
  return _result, _err
}

func _main (args []*string) (_err error) {
  client, _err := CreateClient()
  if _err != nil {
    return _err
  }

  getUserTokenRequest := &dingtalkoauth2_1_0.GetUserTokenRequest{
    ClientId: tea.String("dingxxx"),
    ClientSecret: tea.String("1234"),
    Code: tea.String("abcd"),
    RefreshToken: tea.String("abcd"),
    GrantType: tea.String("authorization_code"),
  }
  tryErr := func()(_e error) {
    defer func() {
      if r := tea.Recover(recover()); r != nil {
        _e = r
      }
    }()
    _, _err = client.GetUserToken(getUserTokenRequest)
    if _err != nil {
      return _err
    }

    return nil
  }()

  if tryErr != nil {
    var err = &tea.SDKError{}
    if _t, ok := tryErr.(*tea.SDKError); ok {
      err = _t
    } else {
      err.Message = tea.String(tryErr.Error())
    }
    if !tea.BoolValue(util.Empty(err.Code)) && !tea.BoolValue(util.Empty(err.Message)) {
      // err contains the code and message properties, which help locate the issue
    }

  }
  return _err
}

func main() {
  err := _main(tea.StringSlice(os.Args[1:]))
  if err != nil {
    panic(err)
  }
}
Node.js
// This file is auto-generated, don't edit it
import Util from '@alicloud/tea-util';
import dingtalkoauth2_1_0, * as $dingtalkoauth2_1_0 from '@alicloud/dingtalk/oauth2_1_0';
import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
import * as $tea from '@alicloud/tea-typescript';

export default class Client {

  /**
   * Initialize the account Client using a Token
   * @return Client
   * @throws Exception
   */
  static createClient(): dingtalkoauth2_1_0 {
    let config = new $OpenApi.Config({ });
    config.protocol = "https";
    config.regionId = "central";
    return new dingtalkoauth2_1_0(config);
  }

  static async main(args: string[]): Promise<void> {
    let client = Client.createClient();
    let getUserTokenRequest = new $dingtalkoauth2_1_0.GetUserTokenRequest({
      clientId: "dingxxx",
      clientSecret: "1234",
      code: "abcd",
      refreshToken: "abcd",
      grantType: "authorization_code",
    });
    try {
      await client.getUserToken(getUserTokenRequest);
    } catch (err) {
      if (!Util.empty(err.code) && !Util.empty(err.message)) {
        // err contains the code and message properties, which help locate the issue
      }

    }    
  }

}

Client.main(process.argv.slice(2));
C#
// This file is auto-generated, don't edit it. Thanks.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

using Tea;
using Tea.Utils;

namespace AlibabaCloud.SDK.Sample
{
    public class Sample 
    {

        /**
         * Initialize the account Client using a Token
         * @return Client
         * @throws Exception
         */
        public static AlibabaCloud.SDK.Dingtalkoauth2_1_0.Client CreateClient()
        {
            AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config();
            config.Protocol = "https";
            config.RegionId = "central";
            return new AlibabaCloud.SDK.Dingtalkoauth2_1_0.Client(config);
        }

        public static void Main(string[] args)
        {
            AlibabaCloud.SDK.Dingtalkoauth2_1_0.Client client = CreateClient();
            AlibabaCloud.SDK.Dingtalkoauth2_1_0.Models.GetUserTokenRequest getUserTokenRequest = new AlibabaCloud.SDK.Dingtalkoauth2_1_0.Models.GetUserTokenRequest
            {
                ClientId = "dingxxx",
                ClientSecret = "1234",
                Code = "abcd",
                RefreshToken = "abcd",
                GrantType = "authorization_code",
            };
            try
            {
                client.GetUserToken(getUserTokenRequest);
            }
            catch (TeaException err)
            {
                if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message))
                {
                    // err contains the code and message properties, which help locate the issue
                }
            }
            catch (Exception _err)
            {
                TeaException err = new TeaException(new Dictionary<string, object>
                {
                    { "message", _err.Message }
                });
                if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message))
                {
                    // err contains the code and message properties, which help locate the issue
                }
            }
        }

    }
}
C
// This file is auto-generated, don't edit it. Thanks.

#include <alibabacloud/dingtalkoauth_2__1__0.hpp>
#include <alibabacloud/open_api.hpp>
#include <boost/any.hpp>
#include <darabonba/core.hpp>
#include <darabonba/util.hpp>
#include <iostream>
#include <map>

using namespace std;

Alibabacloud_Dingtalkoauth2_1_0::Client createClient() {
  shared_ptr<Alibabacloud_OpenApi::Config> config = make_shared<Alibabacloud_OpenApi::Config>();
  config->protocol = make_shared<string>("https");
  config->regionId = make_shared<string>("central");
  return Alibabacloud_Dingtalkoauth2_1_0::Client(config);
}

int main(int argc, char *args[]) {
  args;
  shared_ptr<Alibabacloud_Dingtalkoauth2_1_0::Client> client = make_shared<Alibabacloud_Dingtalkoauth2_1_0::Client>(createClient());
  shared_ptr<Alibabacloud_Dingtalkoauth2_1_0::GetUserTokenRequest> getUserTokenRequest = make_shared<Alibabacloud_Dingtalkoauth2_1_0::GetUserTokenRequest>(map<string, boost::any>({
    {"clientId", boost::any(string("dingxxx"))},
    {"clientSecret", boost::any(string("1234"))},
    {"code", boost::any(string("abcd"))},
    {"refreshToken", boost::any(string("abcd"))},
    {"grantType", boost::any(string("authorization_code"))}
  }));
  try {
    client->getUserToken(getUserTokenRequest);
  }
  catch (std::exception &err) {
    if (!Darabonba_Util::Client::empty(err.code) && !Darabonba_Util::Client::empty(err.message)) {
      // err contains the code and message properties, which help locate the issue
    }
  }
}

Response

Response body

NameTypeExampleDescription
accessTokenStringabcdThe generated accessToken, used for authentication in subsequent API calls.
refreshTokenStringabcdThe generated refresh_token. Use this refresh token to periodically obtain the user’s accessToken.
expireInLong7200Expiration time, in seconds.
corpIdStringcorpxxxxThe organization ID of the selected organization.

Response example

HTTP/1.1 200 OK
Content-Type:application/json

{
  "accessToken" : "abcd",
  "refreshToken" : "abcd",
  "expireIn" : 7200,
  "corpId" : "corpxxxx"
}

Error codes

If an error occurs when calling this API, find the solution by error message in the Error codes (legacy Server-side) document.