Announcing the new CRM Extensions API



Hi everyone,

Today we’re announcing the new CRM Extensions API. CRM Extensions let you build integrations that bring your data and functionality inside the HubSpot CRM, allowing you to surface your own data in a card in the CRM sidebar for contacts, companies, or deals. That card also lets users launch a modal window that can give users access to all of the features inside your software, without leaving the HubSpot CRM.

To learn and to see examples of integrations using CRM Extensions, see the product update here:

For more details on using the CRM Extensions API, see the developer documentation:


I can’t tell you how excited I am about this… we’ve been wanting this, or something like it, since we first started using HubSpot.
I’ve worked through the docs and have created a very basic CRM Extension to test with, however, I can’t find anything about how to deploy an Extension to a Portal or make it available to Portals. Any guidance on this would be helpful, thanks.


Hi @johndcrumpton

Extensions get set up as part of an app. When your app gets installed to a portal, any object types set up for that app also get installed to the portal, so you’d just need to install your app to your portal (installing an app is counted as authorizing your app and also generating the initial access token).


@johndcrumpton – take a look at this post: Using Webhook / Deal Property Changed - Deal Stage

i ran into this exact issue and it’s a little unclear based on the docs on how to get a “test” app installed and working on a test portal.

it boils down to using postman and a browser to link them up in the back-end of the hubspot database.


This is a great feature! I’m excited to start testing it out. Is it on the roadmap to add the ability to have an iframe within the space on the left or does it always have to be a card the way it is in this version of the API? Also, are you looking at adding this kind of functionality say on the dashboard landing page etc?


Thanks for the followup @dadams and @cre.


Ok, I have a simple CRM extension installed in a test portal. I can’t tell you how excited I am about this feature… we’ve been begging for a way to expose some ERP data to HS CRM and this is far better that I was hoping for.

Now I have questions!!

  1. what’s the oath flow look like to revoke an app from a portal? I tried using the delete method here, passing the code returned from authorization… that returned a 204 like the docs said it should, but didn’t actually remove the app. It seems like there should also be a way to revoke the app without that code… developer should be able to pull it from any portal?

2)We do use HS CRM, but my real focus here is for our customer’s HS portals. Our customer base all uses an industry specific ERP. It’s almost always hosted in-house by our customers. I have developed web services to exposes the items we need for CRM from their ERP systems. Each of our customers is a different domain… so I have… and… etc.

When I create an app, with CRM Extensions, I specify the dataFetchUrl that will be used to query data by ALL instances of the app… since each instance of the app needs to look to a different domain, that’s problematic.
I see 3 options:

  1. Hopefully, there’s a way to change the dataFetchUrl on a per-instance basis to point that instance at the right domain?
    2)a pass-through service on my servers that inspects the request from HS and then queries the appropriate client-side api and then passes the response back… seems a bit kludgy, but workable.
    3)spin up a new app (not just a new instance of the same app) for each of our customers. all of the apps would be identical except for the dataFetchUri and baseUrl props. I’m not sure if there’s a hard limit on the number of apps I can have from a single dev portal? I see how I can do all of that via api’s except for actually creating an app… once it’s created I can add the CRM ext. using the app ID. Is there an api endpoint to create the app itself? This also seems kludgy, but the trouble is all up front as opposed to on each query.

Any suggestions? or some option I’m missing?

Thanks again,


@jagee we’re considering some extra options to have more control over the look the card, but overall we want the cards to have keep the look and feel of the CRM, so it’s unlikely that we’ll allow the card itself to contain an iframe.

Nothing specific planned or being worked on at the moment, but adding similar functionality to other parts of HubSpot is something that we’d like to do down the road.


@johndcrumpton deleting the refresh token won’t remove the app from the portal, it just deactivates the token. We don’t have a programmatic way to delete an app at the moment, so a user would need to log into HubSpot and uninstall the integration from the Your integrations page. Can you tell me more about why you’d want to remove an app that way?

Object types can only have one dataFetchUri that will be used, so there would not be a way to set up separate URIs for each installation of your app. For the moment, your option #2 is going to the best way to handle that, having a single app with a single service that can receive the fetch requests and then get the data for the specific customer.


Thanks @dadams
the pass-through service option seemed like the most likely route to me too. Eventually, the option to set dataFetchUrl per install would be very handy.



I added my first CRM extension. I tried to add a “primaryAction”-button with type “ACTION_HOOK”, but it doesnt works.

I added the uri as baseUri and the uri return with status code 200 a json object like this: {“message”:“xxxx”}

What could be the problem?