I am trying to call a shiplogic API (based in AWS), but I get 400 Bad Request
error.
I have tried various ways to request response from the AWS API such as S3, I have tried creating my own signature for a cURL request, and now I am trying this code.
$host = "api.shiplogic.com";
$accessKey = 'AKIA55D****';
$secretKey = 'cx0WDJLNj1Bmn2**';
$requestUrl = 'https://api.shiplogic.com';
$uri = '/tracking/shipments';
$httpRequestMethod = 'GET';
$data = '{"tracking_reference": "M3RPH"}';
require 'AWS/aws-autoloader.php';;
use Aws\Signature\SignatureV4;
use Aws\Credentials\Credentials;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Psr\Http\Client\ClientInterface;
$signature = new SignatureV4('execute-api', 'af-south-1');
$credentials = new Credentials($accessKey, $secretKey);
$psr7Request = new Request($httpRequestMethod, $requestUrl.$uri, ["content-type"=>"application/json"], $data);
$client = new Client([$requestUrl, 'timeout' => 30]);
$sr = $signature->signRequest($psr7Request, $credentials);
$response = $client->send($sr);
var_dump($response);
The short error is: PHP Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: GET https://api.shiplogic.com/tracking/shipments resulted in a 400 Bad Request response: Invalid or incomplete input
The full error is:
PHP Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: `GET https://api.shiplogic.com/tracking/shipments` resulted in a `400 Bad Request` response:
Invalid or incomplete input
in /home/path/myurl.com/path/AWS/GuzzleHttp/Exception/RequestException.php:113
Stack trace:
#0 /home/path/myurl.com/path/AWS/GuzzleHttp/Middleware.php(65): GuzzleHttp\Exception\RequestException::create()
#1 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(204): GuzzleHttp\Middleware::GuzzleHttp\{closure}()
#2 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(153): GuzzleHttp\Promise\Promise::callHandler()
#3 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/TaskQueue.php(48): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}()
#4 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(248): GuzzleHttp\Promise\TaskQueue->run()
#5 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(224): GuzzleHttp\Promise\Promise->invokeWaitFn()
#6 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(269): GuzzleHttp\Promise\Promise->waitIfPending()
#7 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(226): GuzzleHttp\Promise\Promise->invokeWaitList()
#8 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
#9 /home/path/myurl.com/path/AWS/GuzzleHttp/Client.php(129): GuzzleHttp\Promise\Promise->wait()
#10 /home/path/myurl.com/path/apiSign.php(22): GuzzleHttp\Client->send()
#11 {main}
thrown in /home/path/myurl.com/path/AWS/GuzzleHttp/Exception/RequestException.php on line 113
EDIT:
Screenshot of cURL created by Postman
EDIT 2
Response from using $psr7Request = new Request($httpRequestMethod, $requestUrl.$uri.'?tracking_reference=M3RPH');
GuzzleHttp\Psr7\Response Object
(
[reasonPhrase:GuzzleHttp\Psr7\Response:private] => OK
[statusCode:GuzzleHttp\Psr7\Response:private] => 200
[headers:GuzzleHttp\Psr7\Response:private] => Array
(
[Date] => Array
(
[0] => Sat, 30 Jul 2022 09:08:57 GMT
)
[Content-Type] => Array
(
[0] => application/json
)
[Content-Length] => Array
(
[0] => 743
)
[Connection] => Array
(
[0] => keep-alive
)
[Ship-Logic-Request-Id] => Array
(
[0] => e78565f7-3a63-4831-8cdd-f4c720c13f06
)
[Apigw-Requestid] => Array
(
[0] => WEs-jjI6ifMEPcQ=
)
)
[headerNames:GuzzleHttp\Psr7\Response:private] => Array
(
[date] => Date
[content-type] => Content-Type
[content-length] => Content-Length
[connection] => Connection
[ship-logic-request-id] => Ship-Logic-Request-Id
[apigw-requestid] => Apigw-Requestid
)
[protocol:GuzzleHttp\Psr7\Response:private] => 1.1
[stream:GuzzleHttp\Psr7\Response:private] => GuzzleHttp\Psr7\Stream Object
(
[stream:GuzzleHttp\Psr7\Stream:private] => Resource id #45
[size:GuzzleHttp\Psr7\Stream:private] =>
[seekable:GuzzleHttp\Psr7\Stream:private] => 1
[readable:GuzzleHttp\Psr7\Stream:private] => 1
[writable:GuzzleHttp\Psr7\Stream:private] => 1
[uri:GuzzleHttp\Psr7\Stream:private] => php://temp
[customMetadata:GuzzleHttp\Psr7\Stream:private] => Array
(
)
)
)
POSTMAN response from the same call:
{
"shipments": [
{
"provider_id": 10,
"shipment_id": 14135,
"short_tracking_reference": "G9G",
"status": "cancelled",
"shipment_time_created": "2021-05-21T12:12:03.365338Z",
"shipment_time_modified": "2022-05-31T14:00:34.375688Z",
"shipment_collected_date": null,
"shipment_delivered_date": null,
"collection_from": "uAfrica.com",
"delivery_to": "",
"collection_hub": "Gauteng",
"delivery_hub": "Gauteng",
"service_level_code": "ECO",
"tracking_events": [
{
"id": 1940829,
"parcel_id": 0,
"date": "2021-11-22T14:21:00.000529Z",
"status": "delivered",
"source": "corneladmin",
"message": ""
},
{
"id": 1940828,
"parcel_id": 0,
"date": "2021-11-22T14:20:59.925068Z",
"status": "collected",
"source": "corneladmin",
"message": ""
},
{
"id": 1940812,
"parcel_id": 0,
"date": "2021-11-22T14:20:45.323472Z",
"status": "delivered",
"source": "corneladmin",
"message": ""
},
{
"id": 1940811,
"parcel_id": 0,
"date": "2021-11-22T14:20:45.317556Z",
"status": "collected",
"source": "corneladmin",
"message": ""
},
{
"id": 1940755,
"parcel_id": 0,
"date": "2021-11-22T14:19:12.481537Z",
"status": "delivered",
"source": "corneladmin",
"message": ""
},
{
"id": 1940754,
"parcel_id": 0,
"date": "2021-11-22T14:19:12.462331Z",
"status": "collected",
"source": "corneladmin",
"message": ""
},
{
"id": 1940726,
"parcel_id": 0,
"date": "2021-11-22T14:18:37.02554Z",
"status": "delivered",
"source": "sandbox-admin",
"lat": -25.806655,
"lng": 28.334732,
"message": "POD files captured"
},
{
"id": 1940725,
"parcel_id": 0,
"date": "2021-11-22T14:18:37.011858Z",
"status": "collected",
"source": "sandbox-admin",
"message": ""
},
{
"id": 1940713,
"parcel_id": 0,
"date": "2021-11-22T14:18:20.002241Z",
"status": "delivered",
"source": "sandbox-admin",
"lat": -25.806655,
"lng": 28.334732,
"message": "POD files captured"
},
{
"id": 1940712,
"parcel_id": 0,
"date": "2021-11-22T14:18:19.995663Z",
"status": "collected",
"source": "sandbox-admin",
"message": ""
},
{
"id": 332828,
"parcel_id": 0,
"date": "2021-06-04T09:30:36.170053Z",
"status": "cancelled",
"source": "sandbox-admin",
"message": ""
},
{
"id": 254076,
"parcel_id": 0,
"date": "2021-05-21T12:12:03.846219Z",
"status": "submitted",
"source": "sandbox-admin",
"message": ""
}
]
}
]
}
The documentation says that
you need to pass the tracking_reference
parameter on the query string (just as you did with Postman):
https://api.shiplogic.com/tracking/shipments?tracking_reference=G9G
But that's not what your code does:
$data = '{"tracking_reference": "M3RPH"}';
$psr7Request = new Request($httpRequestMethod, $requestUrl.$uri, ["content-type"=>"application/json"], $data)
The exception message clearly shows that the parameter is missing from the URL:
`GET https://api.shiplogic.com/tracking/shipments` resulted in a `400 Bad Request` response
You should do something like this instead:
$psr7Request = new Request($httpRequestMethod, $requestUrl.$uri.'?tracking_reference=M3RPH');