Solved Making POST and GET API calls to receive data (1 Viewer)

sxschech

Registered User.
Local time
Today, 05:55
Joined
Mar 2, 2010
Messages
793
Probably took on more than my current knowledge. Read a few threads here and did searches and read other sites. Have gotten close, still missing something(s) since haven't been able to get the code fully functioning. I had some help setting up the account with someone from Procore API support, but seems like they don't have experience or examples with VBA and Access. They gave me a curl statement and pointed me to the documentation and recommended to construct the API call using that method, which has examples in Node.js, Python3 Curl and C#.

If I open a windows command prompt, I can paste the curl statement they provided and although it generates an error, it does provide the access_token, which I have deleted from the code below and replaced with the terms in UPPER CASE as place holders.
Code:
H:\>curl -F grant_type=client_credentials \ -F client_id=THIS IS CLIENTID \ -F client_secret=THIS IS SECRET  -X POST https://api.procore.com/oauth/token
curl: (3) URL using bad/illegal format or missing URL
curl: (3) URL using bad/illegal format or missing URL
{"access_token":"THIS IS THE RETURN TOKEN","token_type":"Bearer","expires_in":7200,"created_at":1685118709}
H:\>

I then tried to modify it to get the Access token and it returned error message, but did not provide the token unlike the curl statement above which despite the error provided the token.
Code:
Sub GetAuthKey()
'https://forum.asana.com/t/excel-vba-api-token-authentication/49943/9
Dim Request As Object
Dim authKey As String
Dim stUrl As String
Dim response As String

Set Request = CreateObject("MSXML2.XMLHTTP")
stUrl = "https://api.procore.com/oauth/token?client_id=" & gCLIENTID & "client_secret=" & gSECRET
    With Request
        .Open "POST", stUrl, False
        .SetRequestHeader "Content-type", "application/json"
        .send
    End With
    response = Request.responseText
    
    MsgBox response

End Sub

Since I currently can't seem to get the vba working, I copy the token from the command prompt and can use it in the following code, which I based on one of the sites I found at https://forum.asana.com/t/excel-vba-api-token-authentication/49943/9.
Code:
Sub ListRFIS()
'https://forum.asana.com/t/excel-vba-api-token-authentication/49943/9
    Dim Request As Object ', Json As Dictionary
    'Dim sht As Worksheet
    Dim authKey As String
    Dim stUrl As String
    Dim response As String
    
    authKey = gACCESS_TOKEN 'the token copied from the command prompt
    
    'Set sht = Sheet1
    
    '"https://app.asana.com/api/1.0/users/me"
    stUrl = "https://api.procore.com/rest/v1.0/projects/999111/rfis"
'   stUrl = "https://api.procore.com/rest/v1.0/projects/999111/rfis?[created_at]=2023-05-15..2023-05-15"
                                                                                      
    Set Request = CreateObject("MSXML2.XMLHTTP")
    With Request
        .Open "GET", stUrl, False
        .SetRequestHeader "Authorization", "Bearer " & authKey
        .send
    End With
    response = Request.responseText
    MsgBox response
End Sub

The other issue besides the token is trying to do filters, in this example for a date range. The commented out stUrl line as written, when I tried to use it, doesn't get an error message, it still returns all records.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 05:55
Joined
Oct 29, 2018
Messages
21,473
To make sure we guide you towards the right direction, can you please post a link to the API documentation? Thanks.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 05:55
Joined
Oct 29, 2018
Messages
21,473
Code:
With Request 
    .Open "POST", stUrl, False 
    .SetRequestHeader "Content-type", "application/json" 
    .send 
End With
I am thinking you either need more headers in there or you need to send a message "body" to include your client ID and secret.
 

561414

Active member
Local time
Today, 07:55
Joined
May 28, 2021
Messages
280
https://api.procore.com/oauth/token?client_id=" & gCLIENTID & "client_secret=" & gSECRET
This would return something like this:
Rich (BB code):
https://api.procore.com/oauth/token?client_id=123client_secret=secret
Maybe it should look like this:
Rich (BB code):
https://api.procore.com/oauth/token?client_id=123&client_secret=secret

You are probably missing a & symbol there.
 

561414

Active member
Local time
Today, 07:55
Joined
May 28, 2021
Messages
280
here is the link they provided:
Maybe do this:

Code:
requestBody = "{ ""grant_type"": ""authorization_code"", " & _
    """client_id"": ""db0d63cfa7ac3ceed7166081542216ec99e12341300e5e879105e36bd76dbf63"", " & _
    """client_secret"": ""0b57e8d87e35370307ba5f98ad456bd155cabacea56d49994afe083e2eb04b54"", " & _
    """code"": ""8957b84a67f6ae55ab79c9767836a0af30b7fb7e4c36b27434993123cce71ec7"", " & _
    """redirect_uri"": ""http://localhost"", " & _
    """refresh_token"": ""string"" }"

and then .Send requestBody

Or you could put that in a dictionary and convert to json for more elegance.
 

sxschech

Registered User.
Local time
Today, 05:55
Joined
Mar 2, 2010
Messages
793
I tried inserting into the code and replacing the long numbers with the actual numbers, perhaps how I've done it isn't what you guys meant? Still get an error. Then again, I'm not sure what the line that says code is because in the original curl statement Procore gave me, there was no code only client id and client secret. I took a guess that it was the App Version Key because that was the only other long number item I had in my notes. I also tried deleting that row and didn't make a difference.

{"error":"invalid_grant","error_description":"The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."}

Code:
Dim Request As Object
Dim authKey As String
Dim stUrl As String
Dim response As String
Dim requestBody As String

Set Request = CreateObject("MSXML2.XMLHTTP")
requestBody = "{ ""grant_type"": ""authorization_code"", " & _
    """client_id"": ""db0d63cfa7ac3ceed7166081542216ec99e12341300e5e879105e36bd76dbf63"", " & _
    """client_secret"": ""0b57e8d87e35370307ba5f98ad456bd155cabacea56d49994afe083e2eb04b54"", " & _
    """code"": ""8957b84a67f6ae55ab79c9767836a0af30b7fb7e4c36b27434993123cce71ec7"", " & _
    """redirect_uri"": ""http://localhost"", " & _
    """refresh_token"": ""string"" }"stUrl = "https://login.procore.com/oauth/token"
    With Request
        .Open "POST", stUrl, False
        .SetRequestHeader "Content-type", "application/json"
        .send (requestBody)
    End With
    response = Request.responseText
    
    MsgBox response

End Sub
 

561414

Active member
Local time
Today, 07:55
Joined
May 28, 2021
Messages
280
I see that you used the same code key as in the example.
vba8957b84a67f6ae55ab79c9767836a0af30b7fb7e4c36b27434993123cce71ec7
doc8957b84a67f6ae55ab79c9767836a0af30b7fb7e4c36b27434993123cce71ec7
In your documentation, it says that if you're going to use authorization_code for grant_type, you need to do a call to oauth/authorize and receive the code from there
Value of the `authorization_code` retrieved from the `/oauth/authorize` call. Only required when getting a new access code.
Make that call first and you will receive a code value for your request's code key.
"""code"": ""whatever you receive from the /oauth/authorize call"", " & _
 

561414

Active member
Local time
Today, 07:55
Joined
May 28, 2021
Messages
280
I'm not sure what the line that says code is because in the original curl statement Procore gave me, there was no code only client id and client secret
Try this:
Code:
Dim Request As Object
Dim authKey As String
Dim stUrl As String
Dim response As String
Dim requestBody As String

stUrl = "https://login.procore.com/oauth/token"
Set Request = CreateObject("MSXML2.XMLHTTP")
requestBody = "{ ""grant_type"": ""refresh_token"", " & _
    """client_id"": ""db0d63cfa7ac3ceed7166081542216ec99e12341300e5e879105e36bd76dbf63"", " & _
    """client_secret"": ""0b57e8d87e35370307ba5f98ad456bd155cabacea56d49994afe083e2eb04b54""}"
  
    With Request
        .Open "POST", stUrl, False
        .setRequestHeader "Content-type", "application/json"
        .send requestBody
        response = .responseText
    End With
  
    MsgBox response

End Sub
 
Last edited:

sxschech

Registered User.
Local time
Today, 05:55
Joined
Mar 2, 2010
Messages
793
Thanks Edgar, I'll review your messages on Tuesday as they are letting us leave early for memorial day so wrapping things up. Appreciate everyone's help and was not expecting responses so quickly right before a holiday.
 

561414

Active member
Local time
Today, 07:55
Joined
May 28, 2021
Messages
280
For simplicity's sake, it might be a good idea to forget about the tokens, and just authenticate yourself with every call.
Just an idea, always check if the provider has no problem with that. The token architecture is meant for extended usage of the app without requiring constant authentication and, of course, security reasons when the extension of the session is required.
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 13:55
Joined
Sep 12, 2006
Messages
15,657
I will note that it's real hard to use access VBA vith restapi sites, mainly because there's not a lot of help out there for using VBA. There can be a lot of trial and error until you get the right syntax.

You are probably going to need a JSON parser as well.

I helped someone here in the last few months integrate with WooCommerce. I can't remember precisely what vba I posted, and what I put privately, but you might find some useful code.

In passing when you use get, your pc is likely to use cached results, rather than requery the restapi. At some point you may need to use CreateObject("MSXML2.serverXMLHTTP") and set a cached result value of 0, to force a requery with every get request.
 
Last edited:

GPGeorge

Grover Park George
Local time
Today, 05:55
Joined
Nov 25, 2004
Messages
1,869
Probably took on more than my current knowledge. Read a few threads here and did searches and read other sites. Have gotten close, still missing something(s) since haven't been able to get the code fully functioning. I had some help setting up the account with someone from Procore API support, but seems like they don't have experience or examples with VBA and Access. They gave me a curl statement and pointed me to the documentation and recommended to construct the API call using that method, which has examples in Node.js, Python3 Curl and C#.

If I open a windows command prompt, I can paste the curl statement they provided and although it generates an error, it does provide the access_token, which I have deleted from the code below and replaced with the terms in UPPER CASE as place holders.
Code:
H:\>curl -F grant_type=client_credentials \ -F client_id=THIS IS CLIENTID \ -F client_secret=THIS IS SECRET  -X POST https://api.procore.com/oauth/token
curl: (3) URL using bad/illegal format or missing URL
curl: (3) URL using bad/illegal format or missing URL
{"access_token":"THIS IS THE RETURN TOKEN","token_type":"Bearer","expires_in":7200,"created_at":1685118709}
H:\>

I then tried to modify it to get the Access token and it returned error message, but did not provide the token unlike the curl statement above which despite the error provided the token.
Code:
Sub GetAuthKey()
'https://forum.asana.com/t/excel-vba-api-token-authentication/49943/9
Dim Request As Object
Dim authKey As String
Dim stUrl As String
Dim response As String

Set Request = CreateObject("MSXML2.XMLHTTP")
stUrl = "https://api.procore.com/oauth/token?client_id=" & gCLIENTID & "client_secret=" & gSECRET
    With Request
        .Open "POST", stUrl, False
        .SetRequestHeader "Content-type", "application/json"
        .send
    End With
    response = Request.responseText
   
    MsgBox response

End Sub

Since I currently can't seem to get the vba working, I copy the token from the command prompt and can use it in the following code, which I based on one of the sites I found at https://forum.asana.com/t/excel-vba-api-token-authentication/49943/9.
Code:
Sub ListRFIS()
'https://forum.asana.com/t/excel-vba-api-token-authentication/49943/9
    Dim Request As Object ', Json As Dictionary
    'Dim sht As Worksheet
    Dim authKey As String
    Dim stUrl As String
    Dim response As String
   
    authKey = gACCESS_TOKEN 'the token copied from the command prompt
   
    'Set sht = Sheet1
   
    '"https://app.asana.com/api/1.0/users/me"
    stUrl = "https://api.procore.com/rest/v1.0/projects/999111/rfis"
'   stUrl = "https://api.procore.com/rest/v1.0/projects/999111/rfis?[created_at]=2023-05-15..2023-05-15"
                                                                                     
    Set Request = CreateObject("MSXML2.XMLHTTP")
    With Request
        .Open "GET", stUrl, False
        .SetRequestHeader "Authorization", "Bearer " & authKey
        .send
    End With
    response = Request.responseText
    MsgBox response
End Sub

The other issue besides the token is trying to do filters, in this example for a date range. The commented out stUrl line as written, when I tried to use it, doesn't get an error message, it still returns all records.
This presentation is in Spanish, with an English translator. However, JuanJo has a very good handle on using REST API's with Access. I've used his methods a couple of times recently, with success :)
 

sxschech

Registered User.
Local time
Today, 05:55
Joined
Mar 2, 2010
Messages
793
I tried the suggestions from #5 and #10 and both gave the message:
{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."}

Regarding #14, I did look at a bit of that before I posted my original message. Maybe because I had done a lot of searching prior to that, I wasn't able to focus or locate the portion relevant to building the string.

Since the curl statement seems to provide the token after a bit of its own unhappiness, maybe I can go that route? Suggestions on how to shoe horn that into vba, would that be with a shell command, does someone have an example I could try with that?
 

561414

Active member
Local time
Today, 07:55
Joined
May 28, 2021
Messages
280
Ok, so, this works, right?
H:\>curl -F grant_type=client_credentials \ -F client_id=THIS IS CLIENTID \ -F client_secret=THIS IS SECRET -X POST https://api.procore.com/oauth/token
curl: (3) URL using bad/illegal format or missing URL
curl: (3) URL using bad/illegal format or missing URL
{"access_token":"THIS IS THE RETURN TOKEN","token_type":"Bearer","expires_in":7200,"created_at":1685118709}
H:\>

The post in #10 uses this grant type, which is refresh_token:
grant_type: refresh_token

But in the curl statement, you're using client_credentials as grant_type, so we need to send that instead and also modify the url
from https://login.procore.com/oauth/token ❌
to https://api.procore.com/oauth/token ✔️
And send a client_credentials value for the key grant_type
grant_type: client_credentials

To do that, can you try this?
Rich (BB code):
Dim Request As Object
Dim authKey As String
Dim stUrl As String
Dim response As String
Dim requestBody As String

stUrl = "https://api.procore.com/oauth/token"
Set Request = CreateObject("MSXML2.XMLHTTP")
requestBody = "{ ""grant_type"": ""client_credentials"", " & _
    """client_id"": ""YOUR_CLIENT_ID"", " & _
    """client_secret"": ""YOUR_SECRET""}"
    With Request
        .Open "POST", stUrl, False
        .setRequestHeader "Content-type", "application/json"
        .send requestBody
        response = .responseText
    End With

    MsgBox response

End Sub
 
Last edited:

sxschech

Registered User.
Local time
Today, 05:55
Joined
Mar 2, 2010
Messages
793
Thanks Edgar, Post #16 works. Between the time of my last post and seeing your response, I was able to find a code example of how to use Curl directly - grabbing bits from 2 sites as commented in the code block:

Code:
Sub devstackcurl()
'https://www.devhut.net/vba-send-email-using-windows-10-curl/
'https://stackoverflow.com/questions/2784367/capture-output-value-from-a-shell-command-in-vba
'
    Dim stCmd As String
    Dim response As String
    'get the token
    stCmd = "curl -F grant_type=client_credentials \ -F client_id=THEACTUALCLIENTID \ -F client_secret=THEACTUALSECRET  -X POST https://api.procore.com/oauth/token"
    'Debug.Print stCmd  
    response = CreateObject("WScript.Shell").Exec(stCmd).StdOut.ReadAll
End Sub

Interestingly, when I send curl this way, the response comes back clean vs using the command prompt -- that is to say without the errors
curl: (3) URL using bad/illegal format or missing URL

I still haven't been able to figure out how to properly write the string to filter. From the other issue in Post #1:

This was part of the documentation found at https://developers.procore.com/reference/rest/v1/rfis?version=1.0
?page=SOME_INTEGER_VALUE
&per_page=SOME_INTEGER_VALUE
&filters%5Bid%5D=SOME_ARRAY_VALUE
&filters%5Bstatus%5D=SOME_STRING_VALUE
&filters%5Bassigned_id%5D=SOME_STRING_VALUE
&filters%5Bcreated_at%5D=SOME_STRING_VALUE
&filters%5Bresponsible_contractor_id%5D=SOME_INTEGER_VALUE
&filters%5Bcost_code_id%5D=SOME_STRING_VALUE
&filters%5Breceived_from_login_information_id%5D=SOME_STRING_VALUE
&filters%5Bball_in_court_id%5D=SOME_INTEGER_VALUE
&filters%5Blocation_id%5D=SOME_ARRAY_VALUE
&filters%5Bupdated_at%5D=SOME_STRING_VALUE
&filters%5Brfi_manager_id%5D=SOME_INTEGER_VALUE
&search=SOME_STRING_VALUE
&sort%5Battribute%5D=SOME_STRING_VALUE
&sort%5Bdirection%5D=SOME_STRING_VALUE

I've tried variations

Was I supposed to leave in the %5 stuff (I read that these were URL encoding equivalent to brackets []) or perhaps additional quotes somewhere that I missed or do I need to enumerate all the other parameters mentioned above in the order displayed?
 

561414

Active member
Local time
Today, 07:55
Joined
May 28, 2021
Messages
280
Interestingly, when I send curl this way, the response comes back clean vs using the command prompt -- that is to say without the errors
I didn't know you could do that, thanks for letting me know. My setup for this kind of work would include the VBA-JSON module found on github, using dictionaries to first create the object then convert it to JSON, that way my code looks better and I don't have to deal with so much string manipulation, and finally the http library you are using.

Was I supposed to leave in the %5 stuff (I read that these were URL encoding equivalent to brackets []) or perhaps additional quotes somewhere that I missed
It's a matter of testing, have you tried using just the browser for testing? I usually just paste the urls on my browser and see what response I get, it's quicker than guessing the correct vba syntax, so that's the first thing that I do, once it works on my browser, I implement it with VBA.

do I need to enumerate all the other parameters mentioned above in the order displayed?
No, those filters are optional. Only use the ones you need.

They're giving you a list of examples here, they require you to use triple dots and you're using only two. They're also requiring you to use ISO8601 formatting for your dates and you're using another format. So, let's try to adapt one example and check what you get. Use this:
https://api.procore.com/rest/v1.0/projects/999111/rfis?[created_at]="2023-05-15T12:00:00Z...2023-05-29T12:00:00Z"
(Notice your range was may 15 - may 15, I changed it to may 15 to may 29)
Or this:
https://api.procore.com/rest/v1.0/projects/999111/rfis?%5Bcreated_at%5D%3D%222023-05-15T12%3A00%3A00Z...2023-05-29T12%3A00%3A00Z%22
 
Last edited:

561414

Active member
Local time
Today, 07:55
Joined
May 28, 2021
Messages
280
I modified your date range,
from may 15 - may 15
to may 15 - may 29
 

sxschech

Registered User.
Local time
Today, 05:55
Joined
Mar 2, 2010
Messages
793
Good to know about testing directly in the browser.

I tried your suggestion of running in the browser and with both of your examples, it returned all the records (I copied partial result from first record)
[{"id":xxxyyy,"created_at":"2018-12-21T16:44:30Z","initiated_at":"2018-12-
which is the same result I got in my variations in vba.
 

Users who are viewing this thread

Top Bottom