The features described in this guide are in Early Access beta, separate from the CRM development tools to build UI extensions with React as frontend beta for private app UI extension development.
Public apps enable you to authenticate requests to HubSpot's APIs in your project using OAuth. Public apps can be installed in multiple accounts through a streamlined end-user flow, and can be submitted to HubSpot's App Marketplace. When creating using the developer projects framework, public apps can include UI extensions in addition to other app extensions, such as timeline extensions and workflow actions.
Below, learn how to create and configure a public app using projects.
Before getting started, ensure you've also set up the following:
-
Set up your local environment for project development.
-
Create a developer account.
-
In your developer account, create a test account that you can use to install and test the app.
-
Because you'll be using OAuth, you'll need to set up a self-hosted backend environment to complete the OAuth process. If you haven't set up with OAuth with HubSpot before, it's recommended to follow the OAuth quickstart guide. That guide uses a HubSpot-provided Node.js OAuth quickstart app which is configured to work with the example project you'll be creating in this tutorial.
Using the CLI, you can create a project with a public app using any of the following methods:
- Follow the quickstart guide to create an app from a boilerplate project template, which includes a card for contact records.
- Migrate an existing public app to the developer projects framework.
- Create a public app from scratch locally with a developer project.
To create a public app from scratch:
- In the terminal, navigate to the directory that you'll be storing your project files in.
cd path/to/working/directory
- Since you'll need to deploy your project to your app developer account, set it as the default account by running
hs accounts use <accountName>
and selecting your developer account. - Run
hs project create
to create a new project.
xxxxxxxxxx
hs project create
- Follow the prompts in the terminal to enter a name and location for the project.
- When prompted to choose a template, select Create an empty project (no template).
- With your project created, navigate into the newly created directory using the
cd
command.
xxxxxxxxxx
cd <project-directory-name>
- Create the following files and directories:
- In the src directory, create an
app
directory. - In
src/app
, create apublic-app.json
file. Below is the minimum schema required for uploading an app. View the fullpublic-app.json
schema in the App configuration section below.
- In the src directory, create an
Please note:
The uid
value must be a unique value, and cannot be changed after upload. Changing this name later will result in a new app being created and associated with the project on upload. This value is an internal name and won't be exposed to end-users.
xxxxxxxxxx
// Example public-app.json
{
"name": "App name here",
"uid": "immutable-unique-app-id-here",
"description": "An example public app built with developer projects.",
"auth": {
"redirectUrls": ["http://localhost:3000/oauth-callback"],
"requiredScopes": [
"crm.objects.contacts.read",
"crm.objects.contacts.write",
"oauth"
]
}
}
- After saving the file, upload it to your developer account by running
hs project upload
. Then, follow the prompts in the terminal to create the project in your account.
xxxxxxxxxx
hs project upload
Public apps built with projects include a public-app.json
file to configure the app's details, such as its name, scopes, included extension files, and more.
The public-app.json
file uses the following schema:
xxxxxxxxxx
// Example public-app.json
{
"name": "Getting Started App",
"uid": "getting-started-app-uid",
"description": "An example project of how to build a Public App with Developer Projects",
"logo": "./my-company.png",
"allowedUrls": [
"https://app.example.com",
"https://app.example2.com:8080",
"https://api.example.com/user/",
"https://api.example2.com/user"
],
"auth": {
"redirectUrls": ["http://localhost"],
"requiredScopes": [
"crm.objects.contacts.read",
"crm.objects.contacts.write"
],
"optionalScopes": [],
"conditionallyRequiredScopes": []
},
"support": {
"supportEmail": "support@example.com",
"documentationUrl": "https://example.com/docs",
"supportUrl": "https://example.com/support",
"supportPhone": "+18005555555"
},
"extensions": {
"crm": {
"cards": [
{
"file": "./extensions/example-card.json"
}
]
}
},
"webhooks": {
"file": "./webhooks.json"
}
}
Parameter | Type | Description |
---|---|---|
name | String | The app's name. Can be any string up to 200 characters. Must not start or end with a whitespace character. |
uid | String | The app's unique ID. Can be any string up to 64 characters. Characters can be uppercase or lowercase, and can include numbers, underscores (_ ), dashes (- ), and periods (. ). |
description | String | Describes what the app does for the installing user. Can be any string up to 8192 characters. |
logo | String | The file path for the app's logo, which appears next to the app's name. Must be a valid image with one of the following extensions:
|
allowedUrls | Array | An array containing the URLs that the React app is allowed to call. URLs must use the HTTPS scheme and must contain an authority, followed by an optional path prefix if needed. You do not need to add any override URLs specified in local.json to this array.A request URL will match an allowed URL match when:
allowedUrls , but will allow the request through. |
redirectUrls | Array | An array of strings containing the URLs that the OAuth process is allowed to reroute back to. Each app must have at least one auth redirect URL, and it must use HTTPS. The only exception is that http://localhost is allowed for testing. |
advancedScopeSettingsEnabled | Boolean | Configures when optional and conditionally required scopes can be added to your app's auth configuration. When set to false , new scopes for conditionally required or optional scopes cannot be added or enforced (default is true ).Please note: you must set this field to true (or leave unspecified) and declare your app's use of optional and conditionally required scopes when seeking update approval for your App Marketplace app after adding a UI extension. |
requiredScopes | Array | An array of strings listing your app's required scopes. Each app must include at least one scope, and the installing user must grant these scopes to successfully install the app. See full list of scopes. |
optionalScopes | Array | An array of strings listing your app's optional scopes. These scopes can be excluded from the authorization during installation if the account or user installing the app doesn't have the proper permissions. In that case, the scope will not be included in the resulting refresh token or access token. See full list of scopes. |
supportEmail | String | A valid email address that users can contact for support. |
documentationUrl | String | The external URL that users can navigate to for supporting documentation. Must use HTTPS. |
supportUrl | String | The external URL that users can navigate to for additional support. Must use HTTPS. |
supportPhone | String | The phone number that users can contact for support. Must start with a plus sign (+ ). |
extensions | Object | An object that defines the path to the relevant UI extension configuration file for each app card. Multiple extensions can be included as comma-separated file objects in the cards array. |
webhooks | Object | An object that defines the path to the app's webhooks configuration file. |
When building public apps using projects, some features must be updated locally in your project files, while others must be managed in the app settings UI in HubSpot.
The following app details can only be managed in your local project files:
- App name, logo, and description (public.app.json).
- Contact and support information (public.app.json).
- Auth redirect URLs, scopes and scope settings (public.app.json).
- UI extension functionality (
ExtensionFile.jsx
/.tsx
) - Webhooks and webhook settings (webhooks.json)
All other public app features, such as timeline events, will need to be maintained using the in-app app settings page in HubSpot. When a setting can only be managed locally, the app settings page will disable the field and display a lock icon, which you can hover over for more information.
To view and manage your app in HubSpot, including monitoring usage:
- In the left sidebar of your developer account, navigate to Apps.
-
Click the name of the app.
-
On the App Info tab, you can view basic information about your app, such as the app name and description. Fields that are greyed out with a lock icon can only be updated locally.
-
Click the Auth tab to view the app's authentication information, such as App ID, Client ID, Client secret, Install URL, and scopes.
-
In the left sidebar, navigate to Contact & Support to view the app's company information and support details. On this tab, you can also set up a verified domain.
-
In the left sidebar, navigate to Monitoring to monitor your app's usage data. For public apps built with projects, you can also view detailed UI extension logs.
-
In the left sidebar, you can also view the app's features, including:
- Classic CRM cards (separate from the app cards you can build with UI extensions)
- UI extensions
- Timeline events
- Webhooks
- App settings page
On the Monitoring page, you can view logs for the app's UI extensions, including logs for extension rendering and hubspot.fetch()
requests. To view an app's UI extension logs:
-
In the left sidebar of your developer account, navigate to Apps.
-
Click the name of the app.
-
On the app settings page, in the left sidebar, click Monitoring.
-
Click the UI extensions tab.
-
In the table, you can view all logs for the app's included UI extensions. To filter logs by specific criteria, use the Filter by dropdown menus:
- Result: filter logs by the type of result, including error and success logs for extension rendering and
hubspot.fetch()
requests. - CRM object type: filter logs by the type of CRM object associated with the event.
- Extension name: filter logs by extension, which can be useful when your app includes multiple extensions.
- Result: filter logs by the type of result, including error and success logs for extension rendering and
-
To view more details for an event, click the event, then view the right panel.
-
You can use the Log ID or Request ID to search for the event by ID on the UI extensions tab.
-
You can use the Trace ID or Traceparent value to search for the event on the Log traces tab. Alternatively, you can click View log trace to navigate directly to the event on the Log traces tab.
-
Learn more about log traces below.
When troubleshooting errors, log traces are helpful for quickly debugging issues. You can navigate to log traces directly from an event on the UI extensions tab by clicking View log trace, or by searching for the event by trace ID on the Log traces tab.
When viewing the log trace for an event, you'll see a more detailed breakdown of the event, including error details, request timing, and more, in the Log details section.
To delete a public app that was created in a project, you'll first need to delete the project and its association to the app.
To delete a project associated with a public app:
-
In the left sidebar of your developer account, navigate to Projects.
-
Click the name of the project.
-
Click the Settings tab, then click Delete [project name].
-
In the dialog box, enter the project name and click Delete project.
With the project deleted, you can delete the app:
-
In the left sidebar of your developer account, click Apps.
-
Click the name of the app.
-
On the App info tab, in the Delete this app section, click Delete [app name].
-
In the dialog box, click the Export your logs link to export a record of the app's activity. Then, select the I've exported the logs checkbox and click Delete.