Create private apps with projects (BETA)

  • Sales Hub
    • Enterprise
  • Service Hub
    • Enterprise

Create private apps to access your HubSpot data through HubSpot's APIs. Private apps can only be installed into the account where they're defined. Serverless functions can use a private app's access token to authenticate calls to access account data, similar to using an API key but with additional security and usability benefits.

When created as part of a HubSpot project, a private app is stored in a folder that contains an app.json file, and will also contain extension and serverless function files needed by the app. A project can contain multiple apps, and each app can contain multiple UI extensions.

In this guide, learn how to create a private app in a project and view it in HubSpot. Then, you can create a UI extension within the app to customize the CRM UI.

Create a private app within a project

To create a private app in a project, you'll first need to install the HubSpot CLI. To get started with HubSpot projects, you can also check out the quickstart guide.

Please note: you can create up to 20 private apps in a HubSpot account, and each app is subject to HubSpot's API rate limits.

To create a private app within your project:

  • Within the src folder of your project directory, create a folder for your app.
  • Within the app folder, create an app.json file. This file will contain your app definitions.
  • Copy the following code into your app.json file:

name  string

A unique name for the app.

description  string

The app's description.

scopes  array

The app's allowed scopes. At least one scope is required.

uid  string

The app's uniquely identifying name. This can be any string, but should meaningfully identify the app. HubSpot will identify the app by this ID so that you can change the app's name locally or in HubSpot without removing historical or stateful data, such as logs.

public  boolean

Set to false for private apps.

extensions  object

Contains the extensions included in the app. For CRM cards, include a crm object, followed by a cards array that contains a file field that references the CRM card JSON definition file.

If you have not yet defined your extension, you can leave this object empty.

// Example app config file { "name": "Get started App with React", "description": "This is an example of private app that shows a custom card on the Contact record tab built with React-based frontend. This card demonstrates simple handshake with HubSpot's serverless backend.", "scopes": ["", "crm.objects.contacts.write"], "uid": "unique-app-name", "public": false, "extensions": { "crm": { "cards": [ { "file": "extensions/example-card.json" } ] } } }

Add a serverless function to the app

Within the private app, you'll add a serverless function to serve as your UI extension's back end. Serverless function files are stored in a separate folder within the app folder. 

In the app directory, create a .functions directory with the following files:

  • serverless.json
  • package.json
  • example-function.js

The example code below will get you started, but check out the serverless functions guide to learn more about authenticating calls, managing secrets, debugging, and more.


appFunctions  object

The object that contains definitions for each serverless function.

⮑ myFunc  object

The object containing the name of the serverless function file along with any secrets in the secrets array.

myFunc can be any name. You'll later reference this name when using the runServerless method in your React front end.

// Example serverless config file { "runtime": "nodejs18.x", "version": "1.0", "appFunctions": { "myFunc": { "file": "example-function.js", "secrets": [] } } }


// Example serverless function package.json { "name": "demo.functions", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "@hubspot/api-client": "^7.0.1", "axios": "^0.27.2" } }


// Example serverless function exports.main = (context = {}, callback) => { const {text} = context.parameters const ret = `This is coming from a serverless function! You entered: ${text}` try { callback(ret); } catch (error) { callback(error); } };
Screenshot 2023-08-31 at 4.23.46 PMWith your app defined and your serverless function configured, upload the project to HubSpot using the hs project upload command.

On upload, the build will be triggered and HubSpot will validate your project files and provision any needed resources. By default, HubSpot will automatically deploy successful builds. Alternatively, you can link a GitHub repository to the project to automatically trigger a new build when you push a change to the project files in GitHub.

With your app uploaded, learn how to view it in HubSpot below. Then, create a UI extension in the app to customize CRM records with various UI components.

View the app in HubSpot

If you're a super admin, you can access and manage private apps in your HubSpot account, including viewing your apps, their build history, and the access token required to make API calls

To view a private app's details in HubSpot:

  • In your HubSpot account, navigate to CRM Development.
  • In the left sidebar menu, navigate to Private apps.
  • Click the name of the private app.

You'll then be taken to the app's home page where you can view and manage its access token, view request logs and included extensions, and delete the app. Learn more about each tab below.


On the Overview tab, review high-level information about the app's API calls and extension requests and responses.



On the Auth tab, view authentication-related information, such as the private app's access token and scopes. You can also delete the app from this page.



On the Logs tab, view detailed information about the app's various calls and events. The tabs under the Logs tab break down different types of events that occur while the app is running, and are helpful for debugging errors that your app might run into.

  • API calls: click the API calls tab to view logs for API calls made by the app.
  • Serverless functions: click the Serverless functions tab to view logs for serverless functions included in the app. Click an event row to view full the log details in the right panel. Log details will also include a View log trace link that you can click to view the log trace, along with a Trace ID that you can copy for use on the Log Traces tab.
  • Extensions: click the Extensions tab to view React top-level event logs, such as a UI extension successfully loading. Click an event row to view log details, including the user who initialized the request. Log details will also include a View log trace link that you can click to view the log trace, along with a Trace ID that you can copy for use on the Log Traces tab.
  • Security: click the Security tab to view security-related events, such as private app access token viewing and rotating.


As an example, say your app is running into an error when trying to retrieve company proximity information through a serverless function. You can click the Logs tab, then click the Serverless functions tab. Then, you can click the errored request to view the log output in the right panel. In the panel, you can then click View log trace for more information. 


Alternatively, you can click Copy Trace ID in the log output panel, then use the ID in the Log Traces tab.



Log Traces

On the Log Traces tab, view log traces by trace ID, which you can retrieve from log outputs on the Logs tab. Log tracing enables you to trace front-end and back-end logs with a single ID, making it easier to debug issues happening in production.

You can also retrieve log IDs on CRM record pages where an extension has failed to load.

Please note: log tracing is not available for private apps built on platform version 2023.1.




On the Extensions tab, view information about the extensions that are included in the app.



Was this article helpful?
This form is used for documentation feedback only. Learn how to get help with HubSpot.