Mailtrap API - Cannot send emails - "Unauthorized" API error - api

I am using Mailtrap's SMTP to send my development/test e-mails to a fake inbox.
Their SMTP server feature works well, but I'm now trying to implement their API v2 instead.
Every time I hit the https://send.api.mailtrap.io/api/send endpoint, I keep getting the following error:
{"errors":["Unauthorized"]}
More info
I have a Paid account and generated an API Token which has full Admin rights
Only the send.api.mailtrap.io/api/send endpoint fails, other endpoints such as mailtrap.io/accounts are working
I am getting the same error whether I use their API Doc Request testing tool or my code
I am getting the same error message with their API v1
cURL request used (from their API docs)
curl -X POST "https://send.api.mailtrap.io/api/send" \
-H "Accept: application/json" \
-H "Api-Token: xxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"to":[{"email":"john_doe#example.com","name":"John Doe"}],"from":{"email":"sales#example.com","name":"Example Sales Team"},"subject":"Your Example Order Confirmation","html":"<p>Congratulations on your order no. <strong>1234</strong>.</p>"}'
Similar cURL request via PHP (same error message)
<?php
$post = [];
$post['to'] = 'test#test.com';
$post['from'] = ['name' => 'Test', 'email' => 'test#test.com'];
$post['subject'] = 'Test';
$post['html'] = '<h2>This is a test</h2><p>It works!</p>';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://send.api.mailtrap.io/api/send');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Api-Token: xxxxxxxxxxxxxxxxxxxxxxxxx']);
$result = curl_exec($ch);
print_r($result);
echo "\n";

I finally found the answer, here are my conclusions:
As of Today (Sep 2022), Mailtrap's Sending API cannot be used to send e-mails to your Mailtrap Sandbox (i.e. Fake Inbox). It can only be used to send real/production e-mails, to real users.
If your Mailtrap account is older than a year, you will most likely be missing the "Send API" section in your account and only see the "API" section. The only solution to address that was to create a new account.
If you still plan to use Mailtrap's Sending API (to send production e-mails), you will need to reach out to Support for some pre-configuration (This is not mentioned in the documentation) otherwise you will receive "Forbidden" from the API, without any additional details.

Does it mean we needs to write separate logic for dev/staging (using SMTP) and for prod (using API) in our apps? Sounds really strange.

I've looked into this and I have found the solution to your problem.
When looking at the send documentation, it states that you must also include an inbox id in your url and also use the sandbox url.
So, if you change your url from https://send.api.mailtrap.io/api/send to https://sandbox.api.mailtrap.io/api/send/1234567 then it should work - At least it did for me!
You can get the inbox id by going to the specific inbox in the webinterface and copy it from the url.

Related

Cannot retrieve access tocken

I am experimenting with this https://forge-digital-twin.autodesk.io/# using the gitlab code. I can display it locally (without the engine or dataflow) but I can not gain an access token.
I am using the VSCode extension and I get the code 401 (Unauthorized) error if I try to create buckets etc (hence why I am trying to get an access code). However, when I request one using this:
curl -i -X POST 'https://developer.api.autodesk.com/authentication/v1/authenticate' -H 'Content-Type: application/x-www-form-urlencoded' -d 'client_id=-----' -d 'client_secret= ----' -d 'grant_type=client_credentials' -d 'scope=data:write data:read bucket:create bucket:delete'
I get this error:
Invoke-WebRequest : Cannot bind parameter 'Headers'. Cannot convert the "Content-Type:
application/x-www-form-urlencoded" value of type "System.String" to type
"System.Collections.IDictionary".
At line:1 char:90
... ticate' -H 'Content-Type: application/x-www-form-urlencoded' -d 'cl ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidArgument: (:) [Invoke-WebRequest], ParameterBindingException
FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.InvokeWebRe
questCommand
I have no idea where I am going wrong and have tried everything I can think of.
Hope you can help, thanks :)
If you're seeing 401 issues when working with the Forge extension for Visual Studio Code, make sure that you have at least one "environment" configured with your Forge client ID and secret. When you activate the extension for the first time, it should ask you for the credentials automatically, but you can also add or edit the environments at any point by going to the Visual Studio Code preferences, and looking for "forge":
And then, in the Autodesk > Forge: Environments section, hit the Edit in settings.json link and edit the environments directly as JSON, creating a new object (with title, clientId, and clientSecret properties set) if needed:
Btw. VSCode provides intelli-sense support when editing the settings.json file, so you'll see exactly which properties are expected/available in each environment.
It defaults to Invoke-WebRequest.
Try to use Invoke-RestMethod like this:
$Body = #{
grant_type = "client_credentials"
client_id = ""
client_secret = ""
scope = "data:write data:read bucket:create bucket:delete"
}
$Headers = #{
'Content-Type' = 'application/x-www-form-urlencoded'
}
$response = Invoke-RestMethod -Method Post -Uri https://developer.api.autodesk.com/authentication/v1/authenticate' -Headers $Headers -Body $Body

cURL in PHP to extract json

I'm new to using the curl library in php. I have been experimenting with some APIs where I came across this command
curl -i -H "API-KEY:xxxxxx" https://www.experiment.com/api/v2/list/
The API-KEY is given. Request is GET. The return format is in JSON. The service is using REST. I created a small PHP script
$cSession = curl_init();
curl_setopt($cSession,CURLOPT_URL,"https://www.experiment.com/api/v2/list/");
curl_setopt($cSession, CURLOPT_HTTPHEADER, array("API-KEY: XXXXXXXXX"));
$result=curl_exec($cSession);
$result turns out to be false. Is there something I'm missing.
Thanks.

dailyLimitExceededUnreg error with key set in request

I have 3 server keys in my google console for different servers.
In the beginning only one key seemed to work, and that was my local IP address.
After debugging with cURL on the staging server I found that the response was:
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
}
This didn't really make sense to me, because the key was provided and the key was definitely set with the appropriate IP address.
So I started the debugging process and for the staging server I tried some cURL IP discovery tools.
Suddenly icanhazip.com gave me the IPv6 address to my server, after adding this to the Allowed IP list it suddenly worked. Some weird behavior if you ask me.
So I still had my Production server to fix, and I found out that this one doesn't have an IPv6 address. The same tool returns the IPv4 address for me and in my control panel I also didn't set up an IPv6 address.
As google doesn't have a big support platform, I'm hoping someone here has ran into the same problem.
I'm trying to use google's custom search API.
Apparently I was using cURL in the wrong way on my server. It now works like a charm!
(Had to add apostrophes around the URL)
If everything else fails, you could just scrape a google search page and parse the results? Something like this (PHP):
$ch = curl_init ('');
$query = 'Pepijn';
curl_setopt ($ch, CURLOPT_URL, 'http://www.google.com/search?hl=en&tbo=d&site=&source=hp&q='.$query);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
$output = curl_exec($ch);
curl_close($ch);
echo $output;
You would need to "sort" through all the returned html and all, but the results are basically in the list items in #search ol.

Server always responds 200 with curl, but gives error messages when accessed in browser

I'm trying to communicate with a third party server using curl.
The authentication system is as follows:
Use credentials to ask for cookie
Set cookie
Make requests
This in itself has not been a problem and I am able to make requests etc, but whatever I send the server always responds 200 even if i send an invalid data format. If i put the same url in the browser it returns error messages about the invalid format.
Does anyone know why this might be? Thanks in advance,
function go($url,$postvars=null)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookie_.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookie_.txt');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POST,count($postvars));
$postfields = http_build_query($postvars);
curl_setopt($ch, CURLOPT_POSTFIELDS,$postfields);
curl_exec($ch);
curl_close($ch);
}
go($url,$login_array); //login=>'',pass=>''
go($url,$some_request_array);
One very likely possibility is a bug in the server code that means it sends 200 statuses with its error messages. Hence while in the browser it'll be an error message, because that's what is in the body, it'll still be "successful". Put an intercept (firebug network, fiddler, etc) on the browser access and see what the status is.
If this is the case you've two options:
Get the party responsible for the server to fix it.
Parse for the error message yourself, and then treat it as an error condition.

Curl command to test the API

I need to test an API of following spec
URL: http://myapp.com/api/upload/
Method: POST
Parameters:
image: (binary data of image)
returns
a JSON Object
sample php implementation to test the api
<?php
$ch = curl_init();
$url = 'http://myapp.com/api/upload/';
$fields = array('image'=>file_get_contents('profile-pic.jpg'));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_URL, $url);
$json = curl_exec($ch);
echo "\n".$json."\n";
?>
I use RESTClient and Poster extensions to test other api, I'm not sure how to send binary data for a parameter named image with those tools.
How do I test the above api using Curl command?
No luck with this one
curl -X POST --data-binary "image=#test.jpg" "http://myapp.com/api/upload/"
test.jpg is in current directory. I can't change the 3rd party API, to be able to test with other encoding formats.
curl -X POST --data-urlencode 'image#test.jpg' 'http://myapp.com/api/upload'
It’s image#, not image=#.
This is assuming that the image data is urlencoded before sending, which is what I figure the PHP code does.
CURLOPT_POSTFIELDS with a hash array in PHP corresponds to the command line -F option. Thus, it should be something similar to:
curl -F image=#profile-pic.jpg http://myapp.com/api/upload/
If that isn't the exact thing, add '--trace-ascii dump.txt' to get a full trace logged and check that out closely to see what's wrong.