Forum Discussion

Kelemvor's avatar
Kelemvor
Icon for Expert rankExpert
2 years ago

Using Postman to create multiple Websites via API & CSV?

Hi,

I’m testing out creating websites (or resources) via the API.  I have a standard Post working in Postman just fine.  However, when I then try to do the same thing via a CSV file in the Runner section, I’m getting 401 Authorization errors.

When I look at the data that’s being sent, it looks the same as what’s sent when I run it manually.

Is there something special I need to do when running a Post command via the Runner vs the manual Send command?

Thanks.

  • Well, just bumping this because it came up again yesterday.  I was able to create a device group with no issues, but simply by change it from device/groups to website/groups made it all break.  It ended up being the version.  When I tried to add it to the URL it didn’t help.  What seemed to work was to specify it in the header like this:

    Once I did that, everything seemed to start working.  Just in case it comes up for me again, I’m documenting it here.  Or if it helps anyone else, there you go.  :)

  • Anonymous's avatar
    Anonymous

    Ok, are you converting your payload to json before sending it? 

  • Yeah, that’s what I found online, but the Headers section in the script seems to be setting that.

    <# Construct Headers #>
    $auth = 'LMv1 ' + $accessId + ':' + $signature + ':' + $epoch
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $headers.Add("Authorization",$auth)
    $headers.Add("Content-Type",'application/json')

  • Anonymous's avatar
    Anonymous

    You need to set the Content-Type header to application/json. Your request probably didn’t specify the type of content it was passing in so the API doesn’t know how to parse your payload; the api doesn’t assume your payload is json.

  • Any idea what this error means?  Just trying to create a website via the API.  I’m using the same “Data” as I use in Postman and it works fine there, but not from Powershell.  I’m not sure where it’s getting all the CSS stuff from as it’s not in the code anywhere.  I even copied and pasted into Notepad first to try to remove any formatting.

    Invoke-RestMethod : HTTP Status 415 – Unsupported Media Typebody {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}HTTP Status 415 – Unsupported
    Media TypeType Status ReportMessage Unsupported Media TypeDescription The origin server is refusing to service the request because the payload is in a format not supported by this method on the target resource.LogicMonitor Technical Operations
    At line:52 char:13
    + $response = Invoke-RestMethod -Uri $url -Method $httpVerb -Body $data ...
    +             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
        + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
    Status:200

  • The examples on that page and mine above will work with V3, the returned data structure is just different.

  • I’m not familiar with Postman at all myself but one thing about LM API calls is that you need to include any POST/PUT data into the sha256 algorithm that is used in the LMv1 auth header or it will fail. So need to make sure Postman is doing that when using the “Runner” section you talked about.

    For PowerShell, there are some unofficial modules in PSGallery otherwise LM provides some examples at https://www.logicmonitor.com/support/rest-api-developers-guide/v1/rest-api-v1-examples#h-powershell-examples, just add the X-Version header to use APIv3 (v1 and v2 are going to be depreciated soon)

  • This is dirty but should get the idea out there. This was a tab delimeted file not a csv but reading a csv is pretty simple.

    $accessId = ''
    $accessKey = ''

    $ParentFolder = '5937'

    $httpVerb = 'POST'
    $resourcePath = '/device/groups'
    $url = 'https://PORTAL.logicmonitor.com/santaba/rest' + $resourcePath

    $Locations = Import-Csv C:\Users\user\Downloads\folders.txt -Delimiter "`t" -Header "SiteName","Street","City","State","Zip"

    foreach ($Location in $Locations) {
    Write-Host $Location.SiteName
    $data = '{"name":"' + $Location.SiteName + '","parentId":' + $ParentFolder + ',"customProperties":[{"name":"location","value":"' + $Location.Street + ", " + $Location.City + ", " + $Location.State + " " + $Location.Zip + '"}]}'
    $epoch = [Math]::Round((New-TimeSpan -start (Get-Date -Date "1/1/1970") -end (Get-Date).ToUniversalTime()).TotalMilliseconds)
    <# Concatenate Request Details #>
    $requestVars = $httpVerb + $epoch + $data + $resourcePath

    <# Construct Signature #>
    $hmac = New-Object System.Security.Cryptography.HMACSHA256
    $hmac.Key = [Text.Encoding]::UTF8.GetBytes($accessKey)
    $signatureBytes = $hmac.ComputeHash([Text.Encoding]::UTF8.GetBytes($requestVars))
    $signatureHex = [System.BitConverter]::ToString($signatureBytes) -replace '-'
    $signature = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($signatureHex.ToLower()))

    <# Construct Headers #>
    $auth = 'LMv1 ' + $accessId + ':' + $signature + ':' + $epoch
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $headers.Add("Authorization",$auth)
    $headers.Add("Content-Type",'application/json')

    $response = Invoke-RestMethod -Uri $url -Method $httpVerb -Header $headers -Body $data
    }
  • I have no idea.  I don’t know Postman or Python very well, but I do know Powershell.  Although I’ve never used it for doing any API stuff.  Do you have a sample of using Powershell do hit the LM APIs by chance that I could use as a starting point?

    Thanks.

  • Is the pre-request script running each time you are making the call?

    Personally this is something I would use Python or Powershell for. Loop through the items in the csv then call the API or SDK with that.