Search code examples
curlservicem8

Servicem8 API cURL Post


im having a little issue with cURL post commands

curl --user "user:pass" --request POST https://api.servicem8.com/api_1.0/note.json --data '{"note":"AdvNotice 48 Hours","related_object":"company","related_object_uuid":"b1cca357-5e00-464e-b66c-8546d6b4963b"}'

i get the response

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>400 Bad Request</title>
    </head>
    <body>
        <h1>Bad Request</h1>
        <p>Bad Request. No data received in POST</p>
        <hr />
        <address>ServiceM8/1</address>
    </body>
</html>

i have fiddled with this for a little and tried posting this data via REST clients, that work fine but just not in cURL,

any suggestions?

Thanks


Solution

  • There's no good reason I can think of to want to use it in CMD.

    There is however a good reason to want to use it in Windows, without the need for cygwin for instance.

    You can do this in PowerShell.

    First of all

    The -u option in cURL is not portable. You should understand it's a cURL specific feature where it will try a number of common authentication types. In this case, it is basic. So, for good practise, in your scripts and programs, you should use -H "Authorization: Basic <base64-Data>

    For instance;

    If my username was [email protected], and my password was mypassword, the format would be like this:

    • [email protected]:mypassword
    • Transform that into base64 is bXluYW1lQGRvbWFpbi5jb206bXlwYXNzd29yZA==
    • Turn that into an accepted header is:
      Authorization: Basic bXluYW1lQGRvbWFpbi5jb206bXlwYXNzd29yZA==
    • Turn that into a cURL option is:
      -H "Authorization: Basic bXluYW1lQGRvbWFpbi5jb206bXlwYXNzd29yZA=="

    To make a base64 header, is as simple as typing into your GNU terminal:

    echo -n '[email protected]:mypassword' | openssl base64 -base64
    

    Or by using PowerShell builtins:

    [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("[email protected]:mypassword"))) 
    

    Secondly

    You can make a template for this in windows using PowerShell ISE.

    For instance, in ServiceM8, this would list all of your clients:

    $user = '[email protected]'
    $pass = 'myPassword'
    $method = 'GET'
    $base64Creds = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(($user+":"+$pass)))
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $headers.Add("Content-Type", 'application/json')
    $headers.Add("Authorization", $base64Creds)
    $response = Invoke-RestMethod 'https://api.servicem8.com/api_1.0/company.json' -Method $method -Headers $headers
    Write-Output $response
    

    You can post data by changing the $method to POST and adding a content body, like mentioned here:

    Put your parameters in a hash table and pass them like this:

    $postParams = @{username='me';moredata='qwerty'} Invoke-WebRequest
    -Uri http://example.com/foobar -Method POST -Body $postParams

    In PowerShell you could access the properties of the output object. $response.name, $response.billing_address, $response.uuid, etc..

    If you absolutely must use CMD, then I'd suggest wrapping up the above into a ps1 file and executing it from your batch script using powershell -executionPolicy bypass -file "C:\Users\Whatever\MyCmd.ps1"