From 70c80ad420e01810b42399621defa41c255db51e Mon Sep 17 00:00:00 2001
From: box-sdk-build
Date: Thu, 20 Feb 2025 06:41:57 -0800
Subject: [PATCH 1/2] chore: Update .codegen.json with commit hash of codegen
and openapi spec
---
.codegen.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.codegen.json b/.codegen.json
index 496d04e..231225d 100644
--- a/.codegen.json
+++ b/.codegen.json
@@ -1 +1 @@
-{ "engineHash": "8a9cc1d", "specHash": "f20ba3f", "version": "0.5.0" }
+{ "engineHash": "22f85cc", "specHash": "f20ba3f", "version": "0.5.0" }
From 8d261e1de91809345b29f9afb1d015f1117fd8c6 Mon Sep 17 00:00:00 2001
From: box-sdk-build
Date: Fri, 21 Feb 2025 03:14:36 -0800
Subject: [PATCH 2/2] docs: Documentation for Java SDK (box/box-codegen#664)
---
.codegen.json | 2 +-
README.md | 79 +++++-
docs/Authentication.md | 365 +++++++++++++++++++++++++++
docs/Client.md | 178 +++++++++++++
docs/Configuration.md | 51 ++++
migration-guide.md | 560 +++++++++++++++++++++++++++++++++++++++++
6 files changed, 1230 insertions(+), 5 deletions(-)
create mode 100644 docs/Authentication.md
create mode 100644 docs/Client.md
create mode 100644 docs/Configuration.md
create mode 100644 migration-guide.md
diff --git a/.codegen.json b/.codegen.json
index 231225d..d197d53 100644
--- a/.codegen.json
+++ b/.codegen.json
@@ -1 +1 @@
-{ "engineHash": "22f85cc", "specHash": "f20ba3f", "version": "0.5.0" }
+{ "engineHash": "5c674a3", "specHash": "f20ba3f", "version": "0.5.0" }
diff --git a/README.md b/README.md
index bcdd742..c0b9169 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,15 @@
-# Box Java SDK GENERATED
+# Box Java SDK Gen
-We are excited to introduce the Beta Release of the latest generation of Box Java SDK, designed to elevate the developer experience and streamline your integration with the Box Content Cloud.
+[](http://opensource.box.com/badges)
+
+
+
+[](https://coveralls.io/github/box/box-java-sdk-gen?branch=main)
+
+We are excited to introduce the Beta Release of the latest generation of Box Java SDK Gen, designed to elevate the developer experience and streamline your integration with the Box Content Cloud.
With this SDK, you’ll have access to:
@@ -21,9 +27,18 @@ Embrace the new generation of Box SDKs and unlock the full potential of the Box
+- [Box Java SDK Gen](#box-java-sdk-gen)
+- [Table of contents](#table-of-contents)
- [Installing](#installing)
- [Getting Started](#getting-started)
- [Documentation](#documentation)
+- [Upgrades](#upgrades)
+- [Integration Tests](#integration-tests)
+ - [Running integration tests locally](#running-integration-tests-locally)
+ - [Create Platform Application](#create-platform-application)
+ - [Export configuration](#export-configuration)
+ - [Start integration tests](#start-integration-tests)
+- [3rd Party Libraries \& Licenses](#3rd-party-libraries--licenses)
- [Questions, Bugs, and Feature Requests?](#questions-bugs-and-feature-requests)
- [Copyright and License](#copyright-and-license)
@@ -39,7 +54,23 @@ To generate a .jar file download the source code and run the following command:
.jar file will be generated in the build/libs directory.
-Unfortunately, .jar file is not yet available in any artifactory. It will be available there when SDK reaches beta phase.
+The SDK is also available on [Maven Central Repository](https://mvnrepository.com/artifact/com.box/box-java-sdk-gen). To include the SDK in your project, add the following dependency to your `pom.xml` file:
+
+```xml
+
+ com.box
+ box-java-sdk-gen
+ VERSION
+
+```
+
+To include the SDK in your project using Gradle, add the following dependency to your `build.gradle` file:
+
+```gradle
+implementation 'com.box:box-java-sdk-gen:VERSION'
+```
+
+Where `VERSION` is the version of the SDK you want to use. You can find the latest version in the [Maven Central Repository](https://mvnrepository.com/artifact/com.box/box-java-sdk-gen).
# Getting Started
@@ -55,13 +86,53 @@ The example below demonstrates how to authenticate with Developer Token and prin
```java
BoxDeveloperTokenAuth auth = new BoxDeveloperTokenAuth("DEVELOPER_TOKEN");
BoxClient client = new BoxClient(auth);
+client.folders.getFolderItems("0").getEntries().forEach(item -> {
+ System.out.println(item.toString());
+});
```
# Documentation
Browse the [docs](docs/README.md) or see [API Reference](https://developer.box.com/reference/) for more information.
-## 3rd Party Libraries & Licenses
+# Upgrades
+
+The SDK is updated regularly to include new features, enhancements, and bug fixes. If you are upgrading from our legacy SDKs to this new generation SDKs is a straightforward process. Checkout the [migration guide](MIGRATION_GUIDE.md) and [changelog](CHANGELOG.md) for more information.
+
+# Integration Tests
+
+## Running integration tests locally
+
+### Create Platform Application
+
+To run integration tests locally you will need a `Custom App` created in the [Box Developer
+Console](https://app.box.com/developers/console) with `Server Authentication (with JWT)` selected as authentication method.
+Once created you can edit properties of the application:
+
+- In section `App Access Level` select `App + Enterprise Access`. You can enable all `Application Scopes`.
+- In section `Advanced Features` enable `Make API calls using the as-user header` and `Generate user access tokens`.
+
+Now select `Authorization` and submit application to be reviewed by account admin.
+
+### Export configuration
+
+1. Select `Configuration` tab and in the bottom in the section `App Settings`
+ download your app configuration settings as JSON.
+2. Encode configuration file to Base64, e.g. using command: `base64 -i path_to_json_file`
+3. Set environment variable: `JWT_CONFIG_BASE_64` with base64 encoded jwt configuration file
+4. Set environment variable: `BOX_FILE_REQUEST_ID` with ID of file request already created in the user account, `BOX_EXTERNAL_USER_EMAIL` with email of free external user which not belongs to any enterprise.
+5. Set environment variable: `WORKFLOW_FOLDER_ID` with the ID of the Relay workflow that deletes the file that triggered the workflow. The workflow should have a manual start to be able to start it from the API.
+6. Set environment variable: `APP_ITEM_ASSOCIATION_FILE_ID` to the ID of the file with associated app item and `APP_ITEM_ASSOCIATION_FOLDER_ID` to the ID of the folder with associated app item.
+
+### Start integration tests
+
+To run integration tests locally, you can use the following command:
+
+```console
+./gradlew test --stacktrace
+```
+
+# 3rd Party Libraries & Licenses
The Java SDK Gen uses third-party libraries that are required for usage. Their licenses are listed below:
diff --git a/docs/Authentication.md b/docs/Authentication.md
new file mode 100644
index 0000000..8c7fc6c
--- /dev/null
+++ b/docs/Authentication.md
@@ -0,0 +1,365 @@
+# Authentication
+
+
+
+
+- [Authentication](#authentication)
+- [Authentication methods](#authentication-methods)
+ - [Developer Token](#developer-token)
+ - [JWT Auth](#jwt-auth)
+ - [Authenticate Enterprise](#authenticate-enterprise)
+ - [Authenticate user](#authenticate-user)
+ - [Client Credentials Grant](#client-credentials-grant)
+ - [Obtaining Service Account token](#obtaining-service-account-token)
+ - [Obtaining User token](#obtaining-user-token)
+ - [Switching between Service Account and User](#switching-between-service-account-and-user)
+ - [OAuth 2.0 Auth](#oauth-20-auth)
+ - [Authentication with OAuth2](#authentication-with-oauth2)
+ - [Injecting existing token into BoxOAuth](#injecting-existing-token-into-boxoauth)
+- [Retrieve current access token](#retrieve-current-access-token)
+- [Refresh access token](#refresh-access-token)
+- [Revoke token](#revoke-token)
+- [Downscope token](#downscope-token)
+- [Token storage](#token-storage)
+ - [In-memory token storage](#in-memory-token-storage)
+ - [Custom storage](#custom-storage)
+
+
+
+# Authentication methods
+
+## Developer Token
+
+The fastest way to get started using the API is with developer token. A
+developer token is simply a short-lived access token that cannot be refreshed
+and can only be used with your own account. Therefore, they're only useful for
+testing an app and aren't suitable for production. You can obtain a developer
+token from your application's [developer console][dev_console] page.
+
+To create a `BoxClient` with a developer token, construct an `BoxDeveloperTokenAuth`
+object with the `token` set to the developer token and construct the client with that.
+
+
+
+```java
+BoxDeveloperTokenAuth auth = new BoxDeveloperTokenAuth("YOUR-DEVELOPER-TOKEN");
+BoxClient client = new BoxClient(auth);
+```
+
+[dev_console]: https://app.box.com/developers/console
+
+## JWT Auth
+
+Before using JWT Auth make sure you set up correctly your Box platform app.
+The guide with all required steps can be found here: [Setup with JWT][jwt_guide]
+
+### Authenticate Enterprise
+
+JWT auth allows your application to authenticate itself with the Box API
+for a given enterprise. By default, your application has a [Service Account][service_account]
+that represents it and can perform API calls. The Service Account is separate
+from the Box accounts of the application developer and the enterprise admin of
+any enterprise that has authorized the app — files stored in that account are
+not accessible in any other account by default, and vice versa.
+
+If you generated your public and private keys automatically through the
+[Box Developer Console][dev_console], you can use the JSON file created there
+to configure your SDK instance and create a client to make calls as the
+Service Account. Call one of static `BoxJwtAuth` method:
+`JWTConfig.fromConfigFile("PATH_TO_CONFIG_FILE")` and pass JSON file local path
+or `JWTConfig.fromConfigJsonString(CONFIG_JSON_STRING)` and pass JSON config file content as string.
+
+```java
+JWTConfig config = JWTConfig.fromConfigFile("src/example/config/config.json");
+BoxJWTAuth auth = new BoxJWTAuth(config);
+BoxClient client = new BoxClient(auth);
+```
+
+Otherwise, you'll need to provide the necessary configuration fields directly to the `JWTConfig` constructor:
+
+```java
+JWTConfig config = new JWTConfig.JWTConfigBuilder("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET", "JWT_KEY_ID", "PRIVATE_KEY", "PRIVATE_KEY_PASSWORD")
+ .enterpriseId("123456")
+ .build();
+BoxJWTAuth auth = new BoxJWTAuth(config);
+BoxClient client = new BoxClient(auth);
+```
+
+### Authenticate user
+
+App auth applications also often have associated [App Users][app_user], which are
+created and managed directly by the application — they do not have normal login credentials,
+and can only be accessed through the Box API by the application that created them.
+You may authenticate as the Service Account to provision and manage users, or as an individual app user to
+make calls as that user. See the [API documentation](https://developer.box.com/)
+for detailed instructions on how to use app auth.
+
+Clients for making calls as an App User can be created with the same JSON JWT config file generated through the
+[Box Developer Console][dev_console]. Calling `jwtAuth.withUserSubject('USER_ID')` method will return a new auth object,
+which is authenticated as the user with provided id, leaving the original object unchanged.
+
+```java
+JWTConfig config = JWTConfig.fromConfigFile("src/example/config/config.json");
+BoxJWTAuth auth = new BoxJWTAuth(config);
+BoxJWTAuth userAuth = auth.withUserSubject("USER_ID");
+BoxClient userClient = new BoxClient(userAuth);
+```
+
+Alternatively, clients for making calls as an App User can be created with the same `JWTConfig`
+constructor as in the above examples, similarly to creating a Service Account client. Simply pass the
+`userId` instead of `enterpriseId` when constructing the auth config instance:
+
+```java
+JWTConfig config = new JWTConfig.JWTConfigBuilder("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET", "JWT_KEY_ID", "PRIVATE_KEY", "PRIVATE_KEY_PASSWORD")
+ .userId("123456")
+ .build();
+BoxJWTAuth auth = new BoxJWTAuth(config);
+BoxClient client = new BoxClient(auth);
+```
+
+[jwt_guide]: https://developer.box.com/guides/authentication/jwt/jwt-setup/
+[service_account]: https://developer.box.com/guides/getting-started/user-types/service-account/
+[app_user]: https://developer.box.com/guides/getting-started/user-types/app-users/
+
+## Client Credentials Grant
+
+Before using Client Credentials Grant Auth make sure you set up correctly your Box platform app.
+The guide with all required steps can be found here: [Setup with Client Credentials Grant][ccg_guide]
+
+Client Credentials Grant Auth method allows you to obtain an access token by having client credentials
+and secret with enterprise or user ID, which allows you to work using service or user account.
+
+You can use `CCGAuth` to initialize a client object the same way as for other authentication types:
+
+```java
+CCGConfig config = new CCGConfig.CCGConfigBuilder("YOUR_CLIENT", "YOUR_CLIENT_SECRET")
+ .userId("USER_ID")
+ .build();
+BoxCCGAuth auth = new BoxCCGAuth(config);
+BoxClient client = new BoxClient(auth);
+
+UserFull user = client.users.getUserMe();
+System.out.println(user.getName());
+```
+
+Obtained token is valid for specified amount of time, it will be refreshed automatically by default.
+
+### Obtaining Service Account token
+
+The [Service Account](https://developer.box.com/guides/getting-started/user-types/service-account//)
+is separate from the Box accounts of the application developer and the
+enterprise admin of any enterprise that has authorized the app — files stored in that account
+are not accessible in any other account by default, and vice versa.
+To obtain service account you will have to provide enterprise ID with client id and secret:
+
+```java
+CCGConfig config = new CCGConfig.CCGConfigBuilder("YOUR_CLIENT", "YOUR_CLIENT_SECRET")
+ .enterpriseId("ENTERPRISE_ID")
+ .build();
+BoxCCGAuth auth = new BoxCCGAuth(config);
+BoxClient client = new BoxClient(auth);
+```
+
+### Obtaining User token
+
+In order to enable obtaining user token you have to go to your application configuration that can be found
+[here][dev_console]. In `Configuration` tab, in section `Advanced Features`
+select `Generate user access tokens`. Do not forget to re-authorize application if it was already authorized.
+
+To obtain user account you will have to provide user ID with client id and secret.
+
+```java
+CCGConfig config = new CCGConfig.CCGConfigBuilder("YOUR_CLIENT", "YOUR_CLIENT_SECRET")
+ .userId("USER_ID")
+ .build();
+BoxCCGAuth auth = new BoxCCGAuth(config);
+BoxClient client = new BoxClient(auth);
+```
+
+### Switching between Service Account and User
+
+You can easily switch to be authenticated as a Service Account or as a User.
+To create a new auth object authenticated as Service Account you can call:
+
+```java
+BoxCCGAuth enterpriseAuth = auth.withEnterpriseSubject("ENTERPRISE_ID");
+BoxClient enterpriseClient = new BoxClient(enterpriseAuth);
+```
+
+To authenticate with user subject call:
+
+```java
+BoxCCGAuth userAuth = auth.withUserSubject("USER_ID");
+BoxClient userClient = new BoxClient(userAuth);
+```
+
+The new token will be automatically fetched with a next API call.
+
+[ccg_guide]: https://developer.box.com/guides/authentication/client-credentials/client-credentials-setup/
+
+## OAuth 2.0 Auth
+
+### Authentication with OAuth2
+
+If your application needs to integrate with existing Box users who will provide
+their login credentials to grant your application access to their account, you
+will need to go through the standard OAuth2 login flow. A detailed guide for
+this process is available in the
+[Authentication with OAuth API documentation](https://developer.box.com/en/guides/authentication/oauth2/).
+
+Using an auth code is the most common way of authenticating with the Box API for
+existing Box users, to integrate with their accounts.
+Your application must provide a way for the user to login to Box (usually with a
+browser or web view) in order to obtain an auth code.
+
+
+
+```java
+BoxOAuth oauth = new OAuthConfig("CLIENT_ID", "CLIENT_SECRET");
+String authorizationUrl = auoauthth.getAuthorizeUrl();
+```
+
+After a user logs in and grants your application access to their Box account,
+they will be redirected to your application's `redirect_uri` which will contain
+an auth code. This auth code can then be used along with your client ID and
+client secret to establish an API connection.
+You need to provide the auth code to the SDK to obtain an access token.
+Calling `oauth.getTokensAuthorizationCodeGrant('code')` will exchange the auth code for an access token
+and save it in the `BoxOAuth` token storage. The SDK will automatically refresh the token when needed.
+All you need to do is create a client object with the `BoxOAuth` object and start making API calls.
+
+
+
+```java
+auth.getTokensAuthorizationCodeGrant("AUTHORIZATION_CODE");
+BoxClient client = new BoxClient(auth);
+```
+
+### Injecting existing token into BoxOAuth
+
+If you already have an access token and refresh token, you can inject them into the `BoxOAuth` token storage
+to avoid repeating the authentication process. This can be useful when you want to reuse the token
+between runs of your application.
+
+```java
+AccessToken accessToken = new AccessToken.AccessTokenBuilder()
+ .accessToken("ACCESS_TOKEN")
+ .refreshToken("REFRESH_TOKEN")
+ .build();
+auth.tokenStorage.store(accessToken);
+BoxClient client = new BoxClient(auth);
+```
+
+Alternatively, you can create a custom implementation of `TokenStorage` interface and pass it to the `BoxOAuth` object.
+See the [Custom storage](#custom-storage) section for more information.
+
+# Retrieve current access token
+
+After initializing the authentication object, the SDK will be able to retrieve the access token.
+To retrieve the current access token you can use the following code:
+
+
+
+```java
+auth.retrieveToken();
+```
+
+# Refresh access token
+
+Access tokens are short-lived and need to be refreshed periodically. The SDK will automatically refresh the token when needed.
+If you want to manually refresh the token, you can use the following code:
+
+
+
+```java
+auth.refreshToken();
+```
+
+# Revoke token
+
+Access tokens for a client can be revoked when needed. This call invalidates old token.
+For BoxCcgAuth and BoxJwtAuth you can still reuse the `auth` object to retrieve a new token.
+If you make any new call after revoking the token, a new token will be automatically retrieved.
+For BoxOAuth it would be necessary to manually go through the authentication process again.
+For BoxDeveloperTokenAuth, it is necessary to provide a DeveloperTokenConfig during initialization,
+containing the client ID and client secret.
+
+To revoke current client's tokens in the storage use the following code:
+
+
+
+```java
+auth.revokeToken();
+// client's tokens have been revoked
+```
+
+# Downscope token
+
+You can exchange a client's access token for one with a lower scope, in order
+to restrict the permissions for a child client or to pass to a less secure
+location (e.g. a browser-based app).
+
+A downscoped token does not include a refresh token.
+In such a scenario, to obtain a new downscoped token, refresh the original token
+and utilize the newly acquired token to obtain the downscoped token.
+
+More information about downscoping tokens can be found [here](https://developer.box.com/guides/authentication/tokens/downscope/).
+If you want to learn more about available scopes please go [here](https://developer.box.com/guides/api-calls/permissions-and-errors/scopes/#scopes-for-downscoping).
+
+For example to get a new token with only `item_preview` scope, restricted to a single file, suitable for the
+[Content Preview UI Element](https://developer.box.com/en/guides/embed/ui-elements/preview/) you can use the following code.
+You can also initialize `BoxDeveloperTokenAuth` with the retrieved access token and use it to create a new Client.
+
+
+
+```java
+String resource = "https://api.box.com/2.0/files/123456789";
+List scopes = List.of("item_preview");
+AccessToken downscopedToken = auth.downscopeToken(scopes, resource, null, null);
+BoxDeveloperTokenAuth downscopedAuth = new BoxDeveloperTokenAuth(downscopedToken.getAccessToken());
+BoxClient downscopedClient = new BoxClient(downscopedAuth);
+```
+
+# Token storage
+
+## In-memory token storage
+
+By default, the SDK stores the access token in volatile memory. When rerunning your application,
+the access token won't be reused from the previous run; a new token has to be obtained again.
+To use in-memory token storage, you don't need to do anything more than
+create an Auth class using AuthConfig, for example, for OAuth:
+
+```java
+OAuthConfig config = new OAuthConfig("CLIENT_ID", "CLIENT_SECRET");
+BoxOAuth auth = new BoxOAuth(config);
+```
+
+## Custom storage
+
+You can also provide a custom token storage class. All you need to do is create a class that implements `TokenStorage`
+interface and pass an instance of your class to the AuthConfig constructor.
+
+```java
+TokenStorage customTokenStorage = new TokenStorage() {
+ @Override
+ public void store(AccessToken accessToken) {
+ // Store the access token
+ }
+
+ @Override
+ public AccessToken get() {
+ // Retrieve the access token
+ return null;
+ }
+
+ @Override
+ public void clear() {
+ // Clear the access token
+ }
+};
+
+OAuthConfig config = new OAuthConfig.OAuthConfigBuilder("CLIENT_ID", "CLIENT_SECRET")
+ .tokenStorage(customTokenStorage)
+ .build();
+BoxOAuth auth = new BoxOAuth(config);
+```
diff --git a/docs/Client.md b/docs/Client.md
new file mode 100644
index 0000000..5722617
--- /dev/null
+++ b/docs/Client.md
@@ -0,0 +1,178 @@
+# Client
+
+This is the central entrypoint for all SDK interaction. The BoxClient houses all the API endpoints
+divided across resource managers.
+
+
+
+
+- [Client](#client)
+- [Make custom HTTP request](#make-custom-http-request)
+ - [JSON request](#json-request)
+ - [Multi-part request](#multi-part-request)
+ - [Binary response](#binary-response)
+- [Additional headers](#additional-headers)
+ - [As-User header](#as-user-header)
+ - [Suppress notifications](#suppress-notifications)
+ - [Custom headers](#custom-headers)
+- [Custom Base URLs](#custom-base-urls)
+- [Interceptors](#interceptors)
+
+
+
+# Make custom HTTP request
+
+You can make custom HTTP requests using the `client.makeRequest()` method.
+This method allows you to make any HTTP request to the Box API. It will automatically use authentication and
+network configuration settings from the client.
+The method accepts a `FetchOptions` object as an argument and returns a `FetchResponse` object.
+
+## JSON request
+
+The following example demonstrates how to make a custom POST request to create a new folder in the root folder.
+
+```java
+FetchOptions fetchOptions = new FetchOptions.FetchOptionsBuilder("https://api.box.com/2.0/users/me", "GET")
+ .params(new HashMap<>() {{
+ put("fields", "name");
+ }})
+ .build();
+FetchResponse response = client.makeRequest(fetchOptions);
+System.out.println("Status code: " + response.getStatus());
+System.out.println("Response body: " + response.getContent());
+```
+
+## Multi-part request
+
+The following example demonstrates how to make a custom multipart request that uploads a file to a folder.
+
+```java
+List multipartItems = List.of(
+ new MultipartItem.MultipartItemBuilder("attributes")
+ .data(JsonManager.serialize("{\"name\": \"newFileName\", \"parent\": { \"id\": \"0\" }}"))
+ .build(),
+ new MultipartItem.MultipartItemBuilder("file")
+ .fileStream(new FileInputStream(new File("file.txt")))
+ .build()
+);
+FetchOptions fetchOptions = new FetchOptions.FetchOptionsBuilder("https://upload.box.com/api/2.0/files/content", "POST")
+ .contentType("multipart/form-data")
+ .multipartData(multipartItems)
+ .build();
+
+FetchResponse response = client.makeRequest(fetchOptions);
+System.out.println("Status code: " + response.getStatus());
+System.out.println("Response body: " + response.getContent());
+```
+
+## Binary response
+
+The following example demonstrates how to make a custom request that expects a binary response.
+It is required to specify the `responseFormat` parameter in the `FetchOptions` object to "binary".
+
+```java
+FetchOptions fetchOptions = new FetchOptions.FetchOptionsBuilder("https://upload.box.com/api/2.0/files/12345/content", "GET")
+ .responseFormat(ResponseFormat.BINARY)
+ .build();
+FetchResponse response = client.makeRequest(fetchOptions);
+System.out.println("Status code: " + response.getStatus());
+System.out.println("Response body: " + response.getContent());
+```
+
+# Additional headers
+
+BoxClient provides a convenient methods, which allow passing additional headers, which will be included
+in every API call made by the client.
+
+## As-User header
+
+The As-User header is used by enterprise admins to make API calls on behalf of their enterprise's users.
+This requires the API request to pass an As-User: USER-ID header. For more details see the [documentation on As-User](https://developer.box.com/en/guides/authentication/oauth2/as-user/).
+
+The following example assume that the client has been instantiated with an access token belonging to an admin-level user
+or Service Account with appropriate privileges to make As-User calls.
+
+Calling the `client.withAsUserHeader()` method creates a new client to impersonate user with the provided ID.
+All calls made with the new client will be made in context of the impersonated user, leaving the original client unmodified.
+
+
+
+```java
+BoxClient userClient = client.withAsUserHeader('1234567');
+```
+
+## Suppress notifications
+
+If you are making administrative API calls (that is, your application has “Manage an Enterprise”
+scope, and the user signing in is a co-admin with the correct "Edit settings for your company"
+permission) then you can suppress both email and webhook notifications. This can be used, for
+example, for a virus-scanning tool to download copies of everyone’s files in an enterprise,
+without every collaborator on the file getting an email. All actions will still appear in users'
+updates feed and audit logs.
+
+> **Note:** This functionality is only available for approved applications.
+
+Calling the `client.withSuppressedNotifications()` method creates a new client.
+For all calls made with the new client the notifications will be suppressed.
+
+```java
+BoxClient newClient = client.withSuppressedNotifications();
+```
+
+## Custom headers
+
+You can also specify the custom set of headers, which will be included in every API call made by client.
+Calling the `client.withExtraHeaders()` method creates a new client, leaving the original client unmodified.
+
+```java
+BoxClient newClient = client.withExtraHeaders(new HashMap<>() {{
+ put("X-My-Header", "124");
+}});
+```
+
+# Custom Base URLs
+
+You can also specify the custom base URLs, which will be used for API calls made by client.
+Calling the `client.withCustomBaseUrls()` method creates a new client, leaving the original client unmodified.
+
+```java
+BaseUrls baseUrls = new BaseUrls.BaseUrlsBuilder()
+ .baseUrl("https://new-base-url.com")
+ .uploadUrl("https://my-company-upload-url.com")
+ .oauth2Url("https://my-company.com/oauth2")
+ .build();
+BoxClient clientWithCustomBaseUrl = client.withCustomBaseUrls(baseUrls);
+```
+
+# Interceptors
+
+You can specify custom interceptors - methods that will be called just before making a request and right after
+receiving a response from the server. Using these function allows you to modify the request payload and response.
+Interceptor interface accepts two methods with the following signatures:
+
+```java
+FetchOptions beforeRequest(FetchOptions fetchOptions)
+FetchResponse afterRequest(FetchResponse fetchResponse)
+```
+
+You can apply more than one interceptor to the client by passing a list of interceptors to apply.
+Calling the `client.withInterceptors()` method creates a new client, leaving the original client unmodified.
+
+```java
+List interceptors = new ArrayList<>() {
+ {
+ add(new Interceptor() {
+ @Override
+ public FetchOptions beforeRequest(FetchOptions fetchOptions) {
+ return fetchOptions;
+ }
+
+ @Override
+ public FetchResponse afterRequest(FetchResponse fetchResponse) {
+ return fetchResponse;
+ }
+ });
+ }
+};
+BoxClient clientWithInterceptor = client.withInterceptors(interceptors);
+```
diff --git a/docs/Configuration.md b/docs/Configuration.md
new file mode 100644
index 0000000..4f6326c
--- /dev/null
+++ b/docs/Configuration.md
@@ -0,0 +1,51 @@
+# Configuration
+
+
+
+
+- [Configuration](#configuration)
+ - [Max retry attempts](#max-retry-attempts)
+ - [Custom retry strategy](#custom-retry-strategy)
+
+
+
+## Max retry attempts
+
+The default maximum number of retries in case of failed API call is 5.
+To change this number you should initialize `BoxRetryStrategy` with the new value and pass it to `NetworkSession`.
+
+```java
+BoxDeveloperTokenAuth auth = new BoxDeveloperTokenAuth("DEVELOPER_TOKEN");
+NetworkSession session = new NetworkSession.NetworkSessionBuilder()
+ .retryStrategy(new BoxRetryStrategy.BoxRetryStrategyBuilder().maxAttempts(3).build())
+ .build();
+BoxClient client = new BoxClient.BoxClientBuilder(auth)
+ .networkSession(session)
+ .build();
+```
+
+## Custom retry strategy
+
+You can also implement your own retry strategy by subclassing `RetryStrategy` and overriding `shouldRetry` and `retryAfter` methods.
+This example shows how to set custom strategy that retries on 5xx status codes and waits 1 second between retries.
+
+```java
+BoxDeveloperTokenAuth auth = new BoxDeveloperTokenAuth("DEVELOPER_TOKEN");
+RetryStrategy customRetryStrategy = new RetryStrategy() {
+ @Override
+ public boolean shouldRetry(FetchOptions fetchOptions, FetchResponse fetchResponse, int attemptNumber) {
+ return fetchResponse.status >= 500;
+ }
+
+ @Override
+ public double retryAfter(FetchOptions fetchOptions, FetchResponse fetchResponse, int attemptNumber) {
+ return 1.0;
+ }
+};
+NetworkSession session = new NetworkSession.NetworkSessionBuilder()
+ .retryStrategy(customRetryStrategy)
+ .build();
+BoxClient client = new BoxClient.BoxClientBuilder(auth)
+ .networkSession(session)
+ .build();
+```
diff --git a/migration-guide.md b/migration-guide.md
new file mode 100644
index 0000000..4616de6
--- /dev/null
+++ b/migration-guide.md
@@ -0,0 +1,560 @@
+# Migration guide from `box-java-sdk` to `box-java-sdk-gen`
+
+
+
+
+- [Migration guide from `box-java-sdk` to `box-java-sdk-gen`](#migration-guide-from-box-java-sdk-to-box-java-sdk-gen)
+ - [Introduction](#introduction)
+ - [Installation](#installation)
+ - [Maven](#maven)
+ - [Gradle](#gradle)
+ - [Key differences](#key-differences)
+ - [Manager approach](#manager-approach)
+ - [Immutable design](#immutable-design)
+ - [Consistent method signature](#consistent-method-signature)
+ - [Authentication](#authentication)
+ - [Developer Token](#developer-token)
+ - [JWT Auth](#jwt-auth)
+ - [Using JWT configuration file](#using-jwt-configuration-file)
+ - [Providing JWT configuration manually](#providing-jwt-configuration-manually)
+ - [Authenticate user](#authenticate-user)
+ - [Client Credentials Grant](#client-credentials-grant)
+ - [Obtaining Service Account token](#obtaining-service-account-token)
+ - [Obtaining User token](#obtaining-user-token)
+ - [Switching between Service Account and User](#switching-between-service-account-and-user)
+ - [OAuth 2.0 Auth](#oauth-20-auth)
+ - [Get Authorization URL](#get-authorization-url)
+ - [Authenticate](#authenticate)
+ - [Store token and retrieve token callbacks](#store-token-and-retrieve-token-callbacks)
+ - [Downscope token](#downscope-token)
+ - [Revoke token](#revoke-token)
+ - [Configuration](#configuration)
+ - [As-User header](#as-user-header)
+ - [Custom Base URLs](#custom-base-urls)
+
+
+
+## Introduction
+
+The new `box-java-sdk-gen` SDK library, which helps Java developers to conveniently integrate with Box API.
+In the contrary to the previous library (`box-java-sdk`), it is not manually maintained, but auto-generated
+based on Open API Specification. This means you can leverage the most up-to-date Box API features in your
+applications without delay. More information and benefits of using the new can be found in the
+[README](https://github.com/box/box-java-sdk-gen/blob/main/README.md) file.
+
+## Installation
+
+To install a new Box Java SDK GENERATED library, you can use Maven or Gradle. The library is available in the
+[Maven Central Repository](https://search.maven.org/artifact/com.box/box-java-sdk-gen).
+
+The new Box Java SDK GENERATED library could be used in the same project along with the legacy one.
+If you want to use a feature available only in the new SDK, you don't need to necessarily migrate all your code
+to use Box Java SDK GENERATED at once. You can use a new feature from the new library,
+while keeping the rest of your code unchanged. Note that it may be required to use fully qualified class names
+from the new SDK to avoid conflicts with the old one. However, we recommend to fully migrate to the new SDK eventually.
+
+### Maven
+
+To add a dependency to your Maven project, add the following to your `pom.xml` file:
+
+```xml
+
+ com.box
+ box-java-sdk-gen
+ VERSION
+
+```
+
+### Gradle
+
+To add a dependency to your Gradle project, add the following to your `build.gradle` file:
+
+```groovy
+implementation 'com.box:box-java-sdk-gen:VERSION'
+```
+
+## Key differences
+
+### Manager approach
+
+The main difference between the old SDK and the new one is the way how API methods are aggregated into objects.
+
+**Old (`box-java-sdk`)**
+
+Firstly, in the old SDK to be able to perform any action on an API object, e.g. `User`, you first had to create its class.
+To do it is required to call:
+
+```java
+BoxUser user = new BoxUser(api, "12345");
+```
+
+to create a class representing an already existing User with id '12345', or create a new one with a call:
+
+```java
+BoxUser.Info createdUserInfo = BoxUser.createAppUser(api, "A User");
+BoxUser user = new BoxUser(api, createdUserInfo.getID());
+```
+
+Then, you could perform any action on created class, which will affect the user, e.g.
+
+```java
+BoxUser.Info info = user.new Info();
+info.setName(name);
+user.updateInfo(info);
+```
+
+**New (`box-java-sdk-gen`)**
+
+In the new SDK the API methods are grouped into dedicated manager classes, e.g. `User` object
+has dedicated `UserManager` class. Each manager class instance is available in `BoxClient` object.
+The fields storing references to the managers are named in the plural form of the resource that the
+manager handles - `client.users` for `UsersManager`. If you want to perform any operation
+connected with a `User` you need to call a respective method of `UserManager`.
+For example, to get info about existing user you need to call:
+
+```java
+UserFull user = client.users.getUsersById("12345");
+```
+
+or to create a new user:
+
+```java
+CreateUserRequestBody requestBody =
+ new CreateUserRequestBody.CreateUserRequestBodyBuilder("John Doe").build();
+UserFull user = client.users.createUser(requestBody);
+```
+
+The `UserFull` object returned by both of these methods is a data class - it does not contain any methods to call.
+To perform any action on `User` object, you need to still use a `UserManager` method for that.
+Usually these methods have a first argument, which accepts id of the object you want to access,
+e.g. to update a user name, call method:
+
+```java
+UpdateUserByIdRequestBody requestBody =
+ new UpdateUserByIdRequestBody.UpdateUserByIdRequestBodyBuilder().name("Marry").build();
+UserFull updatedUser = client.users.updateUserById(user.getId(), requestBody);
+```
+
+### Immutable design
+
+The new SDK is designed to be mostly immutable. This means that methods,
+which used to modify the existing object in old SDK now return a new instance of the class with the modified state.
+This design pattern is used to avoid side effects and make the code more predictable and easier to reason about.
+Methods, which returns a new modified instance of an object, will always have a prefix `with` in their names, e.g.
+
+**New (`box-java-sdk-gen`)**
+
+```java
+BoxClient client = new BoxClient(auth);
+BoxClient asUserClient = client.withAsUserHeader("USER_ID");
+```
+
+### Consistent method signature
+
+To facilitate easier work with the new SDK, we have changed the API method signatures to be consistent and unified.
+
+**Old (`box-java-sdk`)**
+
+In the old SDK, API methods had numerous parameters, which were not grouped into any objects and were passed as separate arguments, e.g. the method for creating a sign request looked like this:
+
+```java
+public static BoxSignRequest.Info createSignRequest(BoxAPIConnection api, List sourceFiles,
+ List signers, String parentFolderId,
+ BoxSignRequestCreateParams optionalParams)
+```
+
+**New (`box-java-sdk-gen`)**
+
+In the new SDK, we have adopted an approach of aggregating parameters into types based on their nature (path, body, query, headers).
+This can be seen in the example corresponding to the above:
+
+```java
+public SignRequest createSignRequest(
+ SignRequestCreateRequest requestBody, CreateSignRequestHeaders headers)
+```
+
+According to the convention, if an API endpoint requires a parameter placed in the URL path, it will appear at the beginning of our method, such as `fileId` in this case. When a request allows for a body, as in `POST` or `PUT`, the method includes a parameter named `requestBody`. Following that, the method signature may include the `queryParams` parameter, followed by `headers`.
+
+The types of parameters `requestBody`, `queryParams`, and `headers` are specific to each endpoint and, in their definition, encompass all fields allowed by the API.
+
+It's worth noting here that when all fields of a particular type are optional, the entire parameter becomes optional as well. This allows us to pass only the parameters we actually want to provide when calling a given method, without the risk of not providing a sufficient number of parameters.
+
+## Authentication
+
+The Box Java SDK Gen library offers the same authentication methods as the legacy one.
+Let's see the differences of their usage:
+
+### Developer Token
+
+**Old (`box-java-sdk`)**
+
+```java
+BoxAPIConnection api = new BoxAPIConnection("YOUR-DEVELOPER-TOKEN");
+```
+
+The new SDK provides a convenient `BoxDeveloperTokenAuth`, which allows authenticating
+using developer token without necessity to provide a Client ID and Client Secret
+
+**New (`box-java-sdk-gen`)**
+
+```java
+BoxDeveloperTokenAuth auth = new BoxDeveloperTokenAuth("YOUR-DEVELOPER-TOKEN");
+BoxClient client = new BoxClient(auth);
+```
+
+### JWT Auth
+
+#### Using JWT configuration file
+
+**Old (`box-java-sdk`)**
+
+The static method, which reads the JWT configuration file has been changed:
+
+```java
+Reader reader = new FileReader("src/example/config/config.json");
+BoxConfig boxConfig = BoxConfig.readFrom(reader);
+IAccessTokenCache tokenCache = new InMemoryLRUAccessTokenCache(100);
+BoxDeveloperEditionAPIConnection api = BoxDeveloperEditionAPIConnection.getAppEnterpriseConnection(boxConfig, tokenCache);
+```
+
+**New (`box-java-sdk-gen`)**
+
+```java
+TokenStorage tokenStorage = new InMemoryTokenStorage(); // or any other implementation of TokenStorage
+JWTConfig config = JWTConfig.fromConfigFile("src/example/config/config.json", tokenStorage);
+BoxJWTAuth auth = new BoxJWTAuth(config);
+BoxClient client = new BoxClient(auth);
+```
+
+#### Providing JWT configuration manually
+
+Some params in `JWTConfig` constructor have slightly different names than one in old `JWTAuth` class.
+
+**Old (`box-java-sdk`)**
+
+```java
+JWTEncryptionPreferences jwtPreferences = new JWTEncryptionPreferences();
+jwtPreferences.setPublicKeyID("PUBLIC-KEY-ID");
+jwtPreferences.setPrivateKeyPassword("PRIVATE-KEY-PASSWORD");
+jwtPreferences.setPrivateKey("PRIVATE-KEY");
+jwtPreferences.setEncryptionAlgorithm(EncryptionAlgorithm.RSA_SHA_256);
+
+IAccessTokenCache accessTokenCache = new InMemoryLRUAccessTokenCache(100);
+BoxDeveloperEditionAPIConnection api = BoxDeveloperEditionAPIConnection
+ .getUserConnection("USER-ID", "CLIENT-ID","CLIENT-SECRET", jwtPreferences, accessTokenCache);
+
+BoxUser.Info userInfo = BoxUser.getCurrentUser(api).getInfo();
+```
+
+**New (`box-java-sdk-gen`)**
+
+```java
+TokenStorage tokenStorage = new InMemoryTokenStorage();
+JWTConfig config = new JWTConfig.JWTConfigBuilder("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET", "JWT_KEY_ID", "PRIVATE_KEY", "PRIVATE_KEY_PASSWORD")
+ .enterpriseId("123456")
+ .tokenStorage(tokenStorage)
+ .build();
+BoxJWTAuth auth = new BoxJWTAuth(config);
+BoxClient client = new BoxClient(auth);
+```
+
+#### Authenticate user
+
+In old SDK method for user authentication was named `BoxDeveloperEditionAPIConnection getUserConnection(String userId, BoxConfig boxConfig, IAccessTokenCache accessTokenCache)`
+and was accepting user id. The method was returning a new instance of `BoxDeveloperEditionAPIConnection` class, which was exchanging the existing token with the one with the user access.
+
+**Old (`box-java-sdk`)**
+
+```java
+BoxDeveloperEditionAPIConnection api = BoxDeveloperEditionAPIConnection.getUserConnection("USER_ID", boxConfig, tokenCache);
+```
+
+**New (`box-java-sdk-gen`)**
+
+In new SDK, to authenticate as user you need to call
+`public BoxJWTAuth withUserSubject(String userId, TokenStorage tokenStorage)` method with id of the user
+to authenticate. The method returns a new instance of `BoxJWTAuth` class, which will perform authentication call
+in scope of the user on the first API call. The `tokenStorage` parameter is optional and allows to provide a custom
+token storage for the new instance of `BoxJWTAuth` class. The new auth instance can be used to create a new user client
+instance.
+
+```java
+BoxJWTAuth userAuth = auth.withUserSubject("USER_ID");
+BoxClient userClient = new BoxClient(userAuth);
+```
+
+### Client Credentials Grant
+
+#### Obtaining Service Account token
+
+To authenticate as enterprise, the only difference between the old and the new SDK,
+is using the `CCGConfig` as a middle step.
+
+**Old (`box-java-sdk`)**
+
+```java
+BoxCCGAPIConnection api = BoxCCGAPIConnection.applicationServiceAccountConnection(
+ "client_id",
+ "client_secret",
+ "enterprise_id"
+);
+```
+
+**New (`box-java-sdk-gen`)**
+
+```java
+CCGConfig config = new CCGConfig.CCGConfigBuilder("YOUR_CLIENT", "YOUR_CLIENT_SECRET")
+ .enterpriseId("ENTERPRISE_ID")
+ .build();
+BoxCCGAuth auth = new BoxCCGAuth(config);
+BoxClient client = new BoxClient(auth);
+```
+
+#### Obtaining User token
+
+To authenticate as user, the only difference between the old and the new SDK, is using the `CCGConfig` as a middle step.
+
+**Old (`box-java-sdk`)**
+
+```java
+BoxCCGAPIConnection api = BoxCCGAPIConnection.userConnection(
+ "client_id",
+ "client_secret",
+ "user_id"
+);
+```
+
+**New (`box-java-sdk-gen`)**
+
+```java
+CCGConfig config = new CCGConfig.CCGConfigBuilder("YOUR_CLIENT", "YOUR_CLIENT_SECRET")
+ .userId("USER_ID")
+ .build();
+BoxCCGAuth auth = new BoxCCGAuth(config);
+BoxClient client = new BoxClient(auth);
+```
+
+### Switching between Service Account and User
+
+In old SDK, if you want to switch between the Service Account and User, you need to create another API connection.
+
+In the new SDK, to keep the immutability design, the methods switching authenticated subject were replaced with methods
+returning a new instance of `BoxCCGAuth` class. The new instance will fetch a new token on the next API call.
+The new auth instance can be used to create a new client instance. You can also specify `tokenStorage` parameter
+to provide a custom token storage for the new instance.
+The old instance of `BoxCCGAuth` class will remain unchanged and will still use the old token.
+
+**New (`box-java-sdk-gen`)**
+
+```java
+BoxCCGAuth userAuth = auth.withUserSubject("USER_ID");
+BoxClient userClient = new BoxClient(userAuth);
+```
+
+```java
+BoxCCGAuth entAuth = auth.withEnterpriseSubject("ENTERPRISE_ID");
+BoxClient entClient = new BoxClient(entAuth);
+```
+
+### OAuth 2.0 Auth
+
+#### Get Authorization URL
+
+To get authorization url in the new SDK, you need to first create the `BoxOAuth` class using
+`OAuthConfig` class. Then to get authorization url, call
+`public String getAuthorizeUrl(GetAuthorizeUrlOptions options)`. Note that this method accepts the instance of `GetAuthorizeUrlOptions` class, which allows specifying extra options to API call.
+
+**Old (`box-java-sdk`)**
+
+In the old SDK, we did not have any method to get the authorization URL. Instead, we had to manually create the URL.
+
+```java
+String authorizationUrl = "https://account.box.com/api/oauth2/authorize?client_id=[CLIENT_ID]&response_type=code";
+```
+
+**New (`box-java-sdk-gen`)**
+
+```java
+BoxOAuth auth = new BoxOAuth(new OAuthConfig.OAuthConfigBuilder("CLIENT_ID", "CLIENT_SECRET").build());
+String authorizationUrl = auth.getAuthorizeUrl();
+```
+
+#### Authenticate
+
+The method for authenticating using the authorization code has been changed. With the old SDK, you had to provide the authorization code to the `BoxAPIConnection` class constructor. In the new SDK, you need to call the `public AccessToken getTokensAuthorizationCodeGrant(String authorizationCode)` method of the `BoxOAuth` class.
+The method now returns an AccessToken object with `accessToken` and `refreshToken` fields,
+while the old one was creating a new instance of `BoxAPIConnection` class.
+
+**Old (`box-java-sdk`)**
+
+```java
+BoxAPIConnection client = new BoxAPIConnection(
+ "[CLIENT_ID]",
+ "[CLIENT_SECRET]",
+ "[CODE]"
+);
+```
+
+**New (`box-java-sdk-gen`)**
+
+```java
+auth.getTokensAuthorizationCodeGrant("AUTHORIZATION_CODE");
+BoxClient client = new BoxClient(auth);
+```
+
+### Store token and retrieve token callbacks
+
+In the new SDK you can define your own class delegated for storing and retrieving a token. It has to inherit from
+`TokenStorage` and implement all of its abstract methods. Next step would be to pass an instance of this class to the
+AuthConfig constructor.
+
+**New (`box-java-sdk-gen`)**
+
+```java
+TokenStorage customTokenStorage = new TokenStorage() {
+ @Override
+ public void store(AccessToken accessToken) {
+ // Store the access token
+ }
+
+ @Override
+ public AccessToken get() {
+ // Retrieve the access token
+ return null;
+ }
+
+ @Override
+ public void clear() {
+ // Clear the access token
+ }
+};
+
+OAuthConfig config = new OAuthConfig.OAuthConfigBuilder("CLIENT_ID", "CLIENT_SECRET")
+ .tokenStorage(customTokenStorage)
+ .build();
+BoxOAuth auth = new BoxOAuth(config);
+```
+
+or reuse one of the provided implementations: `InMemoryTokenStorage`:
+
+```java
+TokenStorage tokenStorage = new InMemoryTokenStorage();
+OAuthConfig config = new OAuthConfig.OAuthConfigBuilder("CLIENT_ID", "CLIENT_SECRET")
+ .tokenStorage(tokenStorage)
+ .build();
+BoxOAuth auth = new BoxOAuth(config);
+```
+
+### Downscope token
+
+The process of downscoping token in the new SDK is similar to the old one. The main difference is that in the new SDK
+you need to call `downscopeToken` method of the `BoxOAuth` class instead of `getLowerScopedToken` method of the `BoxAPIConnection` class.
+
+**Old (`box-java-sdk`)**
+
+```java
+BoxAPIConnection api = new BoxAPIConnection("YOUR-ACCESS-TOKEN");
+
+String resource = "https://api.box.com/2.0/files/RESOURCE-ID";
+List scopes = new ArrayList();
+scopes.add("item_preview");
+scopes.add("item_content_upload");
+
+ScopedToken token = api.getLowerScopedToken(scopes, resource);
+```
+
+**New (`box-java-sdk-gen`)**
+
+```java
+String resource = "https://api.box.com/2.0/files/123456789";
+List scopes = List.of("item_preview");
+AccessToken downscopedToken = auth.downscopeToken(scopes, resource, null, null);
+BoxDeveloperTokenAuth downscopedAuth = new BoxDeveloperTokenAuth(downscopedToken.getAccessToken());
+BoxClient downscopedClient = new BoxClient(downscopedAuth);
+```
+
+### Revoke token
+
+To revoke current client's tokens in the new SDK, you need to call `revokeToken` method of the auth class instead of
+`revoke` method.
+
+**Old (`box-java-sdk`)**
+
+```java
+BoxAPIConnection api = new BoxAPIConnection("YOUR-ACCESS-TOKEN");
+api.revokeToken();
+```
+
+**New (`box-java-sdk-gen`)**
+
+```java
+client.auth.revokeToken()
+```
+
+## Configuration
+
+### As-User header
+
+The As-User header is used by enterprise admins to make API calls on behalf of their enterprise's users.
+This requires the API request to pass an `As-User: USER-ID` header. The following examples assume that the client has
+been instantiated with an access token with appropriate privileges to make As-User calls.
+
+In old SDK you could call client `asUser(String userID)` method to create a new client to impersonate the provided user.
+
+**Old (`box-java-sdk`)**
+
+```java
+BoxAPIConnection api = new BoxAPIConnection("YOUR-ACCESS-TOKEN");
+api.asUser("USER-ID");
+```
+
+**New (`box-java-sdk-gen`)**
+
+In the new SDK the method was renamed to `withAsUserHeader` in the `BoxClient` class,
+and returns a new instance of `BoxClient` class with the As-User header appended to all API calls made by the client.
+The method accepts only user id as a parameter.
+
+```java
+BoxClient userClient = client.withAsUserHeader("USER-ID");
+```
+
+Additionally `BoxClient` offers a `withExtraHeaders(Map extraHeaders)`
+method, which allows you to specify the custom set of headers, which will be included in every API call made by client.
+Calling the `client.withExtraHeaders()` method creates a new client, leaving the original client unmodified.
+
+```java
+BoxClient clientWithExtraHeaders = client.withExtraHeaders(new HashMap<>() {{
+ put("X-My-Header", "124");
+}});
+
+```
+
+### Custom Base URLs
+
+**Old (`box-java-sdk`)**
+
+In old SDK you could specify the custom base URLs, which will be used for API calls made by setting
+the new values of static variables of the `API` class.
+
+```java
+BoxAPIConnection api = new BoxAPIConnection("YOUR-DEVELOPER-TOKEN");
+api.setBaseAppUrl("https://example.app.com");
+api.setBaseURL("https://example.com");
+api.setUploadURL("https://upload.example.com");
+api.setTokenURL("https://example.com/token");
+```
+
+**New (`box-java-sdk-gen`)**
+
+In the new SDK this functionality has been implemented as part of the `BoxClient` class.
+By calling the `client.withCustomBaseUrls()` method, you can specify the custom base URLs that will be used for API
+calls made by client. Following the immutability pattern, this call creates a new client, leaving the original client unmodified.
+
+```java
+BaseUrls baseUrls = new BaseUrls.BaseUrlsBuilder()
+ .baseUrl("https://new-base-url.com")
+ .uploadUrl("https://my-company-upload-url.com")
+ .oauth2Url("https://my-company.com/oauth2")
+ .build();
+BoxClient clientWithCustomBaseUrl = client.withCustomBaseUrls(baseUrls);
+```