Can't make a PHP POST request to the Canvas API

Jump to solution
kreut
Community Explorer

Hi,

I'm trying to make my first API calls using my Canvas token.  I'm able to to do GET requests via PHP but I'm having problems doing POST requests.  Below is a copy of my unsuccessful POST request via PHP (no errors but after listing the external tools, I can see that I'm not actually creating one and I'm not getting any sort of json back) and my successful POST with cURL via the terminal.  I've changed the url and secret key information.  

Might anyone be able to spot the issue?

url = 'https://some_url.com/api/v1/courses/1463675/external_tools';

$data = [
'name' => 'First tool',
'privacy_level' => 'name_only',
'consumer_key' => 'mykey',
'shared_secret' => 'mysecret',
'url'=>'https://example.com/ims/lti'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$authorization = "Authorization: Bearer " . CANVAS_TOKEN;
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', $authorization]);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);


$result = curl_exec($ch); // Execute the cURL statement

curl_close($ch); // Close the cURL connection
var_dump($result);

curl -X POST 'https://some_url.com/api/v1/courses/1463675/external_tools' \
-H "Authorization: Bearer my_super_secret_key" \
-F 'name=First Tool' \
-F 'consumer_key=asdfg' \
-F 'shared_secret=lkjh' \
-F 'url=https://example.com/ims/lti' \
-F 'privacy_level=name_only' \
-F 'custom_fields[key1]=value1' \
-F 'custom_fields[key2]=value2' \
-F 'course_navigation[text]=Course Materials' \
-F 'course_navigation[enabled]=true'
Labels (1)
1 Solution
James
Community Champion

 @kreut  

The first thing I notice is that you are sending mixed signals to the server. You're telling it to use JSON, but then you're sending it a url-encoded payload.

If you use content-type:application/json, then you need to json_encode() your object before adding it to CURLOPT_POSTFIELDS.

If you do not specify the content-type, then you should just put your object into CURLOPT_POSTFIELDS without encoding it and it will convert it for you.

You shouldn't (it may work, but not recommended) use http_build_query() with a POST, that's for GET (since there is no content-type) and some PUT (so you can avoid content-type).

View solution in original post