Simple (I think) requirement for CRM Extensions API



Hi there. I'm new to this forum so bear with my ignorance of the Hubspot API.....

I have what I think is a simple requirement; I would like to present an extra option to the user whenever he/she clicks the Actions drop-down for any contact.

The option will be called "Add A Quote", and the action of the click will be to open a pop-window which will show the Add Quote option from another CRM system. No POSTed variables, nothing fancy, just a URL that opens in a pop-up window.

What's the most effective way to do this? I have read the documentation about the CRM Extensions API, so I think that's the way forward, but that's as far as I've got at the moment.

I'm fairly experienced in API coding to push and pull data between systems but this is a new area for me.

Any suggestions gratefully received.


One thing that would be useful is a sample of the code that is shown in


We want to "surface" a link to our Customer Portal application using the CRM Extensions API.
Ideally this link should be in the Actions drop down list below the contact name, although it would also be acceptable to locate it on the sidebar, as long as it is the next card after the contact name.

The card or action should simply be a link with the text, ”Add a Quote”, and clicking on that link will trigger a process.

The process will be:

  1. Check if the customer (Company) exists on our Customer Portal. If not, add the company by calling an API (I would expect to see a screen throbber whilst the add company is processing):

POST /customers/ HTTP/1.1
Accept: application/vnd.xtrf-v1+json{
"name": "Jan",
"fullName": "Kowalski",
"contact": {
"emails": {
"primary": ""
"billingAddress": {
"addressLine1": "Cracow address 1",
"city": "Cracow",
"countryId": 100

  1. Check if the contact (person) exists on our Customer Portal. If not, add the contact by calling an API (I would expect to see a screen throbber whilst the add contact is processing):
    POST /customers/persons/ HTTP/1.1
    Accept: application/vnd.xtrf-v1+json{
    "name": "Nowy",
    "customerId": 111,
    "contact": {
    "emails": {
    "primary": ""

  2. Then, with the customer and contact defined, open a pop-up window into the Customer Portal and display the Add Quote screen:

Our Sales staff can then follow their internal procedures to add the quote to our Customer Portal.

  1. Once the quote has been completed, the pop-up window can be closed and focus will return to the Hubspot contact screen. A background process will be triggered on completion of the quote which will add a corresponding deal to Hubspot.


Hi @mike.mackechnie, These functionalities should exist. Action hook actions are what you'll want to send your POST requests: For the popup screen via iFrame, you can set that with an action type: Here's a very simple (static) example: - and what it looks like in HubSpot:


Thanks for this Connor.

Forgive my ignorance, but where do you code this action? I think I can figure out the JSON I need to code, but I don't see how I code the POST request.

I have a developer account, and I have created a public app called Hubspot XTRF API(, but I don't see anywhere to actually write the code and I don't know how to integrate that into the live application once it has been tested.

Sorry but I think I'm going to need some hand-holding with this.


Hey @mike.mackechnie, you'd code this wherever you application (i.e. the actual code that makes your app run is deployed). No code is actually written from within the developer account. For example, I pushed my code here up to heroku, so that's where my code lives. An example way to POST data would be to have this structure returned and ready to use when you load up a contact company or deal:

  "type": "ACTION_HOOK",
  "httpMethod": "POST",
  "uri": "",
  "label": "Example action",
  "associatedObjectProperties": [

You'd handle your POST and GET routes from within your application, wherever it may be hosted, and format the JSON in the above way so that any time your specified objects from your dev account are loaded, the request URL defined in the settings is requested, and those actions defined within your application are then available to use. Here are a few examples of how my dev account settings looks:


Hi Connor, thanks for this. I was on another project last week so had leave this for a few days.

I can see now that the Data Fetch URI needs to be where I put my code.

Could I take a peek at your code at I just want to make sure that I code the Post JSON code correctly - I assume you're using cURL?


Hey @mike.mackechnie, I'm actually just returning a static object. I'm using Node and Express:

You could try using to host your own project without having to push to heroku or anything like that in order to test.


Thanks again Connor...

Ok I'm taking this one step at a time. I've copied your code from github to so that I've got, which does the same as your

So far so good..

I've reproduced your object types in my Developer Portal, but I've still got nothing coming back to my contacts in the live account. I'm guessing that I need to code an action hook somewhere....

What's the next step?


Hey @mike.mackechnie, looks good so far. The only thing I can think of is that you haven't installed that application in your live account. What is the HubID of your live production account? You should go through the OAuth flow for this particular app in order to install it.


The ID of my live account is 3538805. I'm going to read up the documentation section on OAuth now.


Ok - progress... I used and was granted access to Contacts and the Workflows API (not sure if I need them but it's a start).


As per the instructions in the OAuth flow, steps 1 and 2 are completing successfully up to the receipt of the code -

However when I plug this code into the request for an access token I get the following:

"status": "BAD_AUTH_CODE",
"message": "missing or unknown auth code",
"correlationId": "5b9a52f5-fedc-40dc-8348-ab8b503b4c60",
"requestId": "6337c4c5d41b6a87c1448bf1ac84fe25"


Hi @mike.mackechnie, it looks like you have a ? after your redirect URI instead of a &. The code parameter must be separate from the redirect uri, and the redirect uri must be exactly what you use when you set up the scopes... I.e. it must be exactly what you have in the redirect_uri param here:

Here's what this looks like in Postman for my application:

Hope this helps!


Thank you sir!
I now have my tokens. Onto the next step....


Hey @mike.mackechnie, sorry, just so I'm understanding you, do you still need help with this one? The application should be installed when you hit this screen and select your production portal.

Once the app has been installed and can be found in your integrations settings: then you should be able to use CRM extensions!


Hi @Connor_Barley thanks for your help so far - this is starting to look like the outcome that I'm after; One question immediately springs to mind when I see the Contact details screen; can we move the generated card up to the top of the screen? My screenshot shows what I mean.

My next step is to code the Action hook to create the pop-up window. If I have any issues with that, I'll raise a new ticket.


Hey @mike.mackechnie, no problem!

You should be able to drag the card up a bit


Great! That works fine.

Of course my next move was to show this to our Sales Manager - so she's really excited now... tomorrow I will code the Action Hook - fingers crossed!


Sweet! CRM extensions are pretty cool. Ping me here when you're done, I'd love to see what your use case :slight_smile: