09-05-2023 06:51 AM - edited 09-06-2023 09:15 PM
For some reason, the exact same credentials, data and endpoint work fine when I do a CURL request:
curl -i -X POST -u apikey:secret 'https://numbers.api.sinch.com/v1/projects/{project_id}/availableNumbers:rentAny' \ -H 'Content-Type: application/json' \ -d '{ "regionCode": "US", "type": "LOCAL", "numberPattern": { "pattern": "206", "searchPattern": "START" }, "smsConfiguration": { "servicePlanId": "service_plan_id" } }'
But when I use my Ruby console, and try to do this through a REST Client, I get the following error:
RestClient::MovedPermanently (301 Moved Permanently)
What's a common reason for the 301 error?
Solved! Go to Solution.
09-07-2023 07:06 PM
For those who need help with the 301 error:
I had an extra / in the URL. Make sure that the URL is 100% matching.
For those who are getting a similar "invalid character" 400 error with a rest client:
Try converting your payload into a JSON string. All that I had to do here, was make payload = payload.to_json
09-05-2023 07:30 AM
Hi,
In your ruby HTTP client you are not handling redirects by the sound of it, whereas curl is. Can you check how to handle redirects automatically with Ruby HTTP?
Regards,
Roland-Ian
09-06-2023 10:47 PM - edited 09-06-2023 10:51 PM
Thank you for the response!
So basically, I'm using this standard gem https://rubygems.org/gems/rest-client/versions/1.6.9?locale=en
Since you commented, I realized that I had an extra "/" in the endpoint. So to anyone stumbling on this thread, that's probably your answer.
But now I'm getting a "400 Bad Request" error, with the same exact variables that I'm putting into my CURL request.
I copied all of the parameters, and put them directly into my console:
> opts = {:method=>:post, :payload=>{:smsConfiguration=>{:servicePlanId=>"{service_plan_id}"}, :regionCode=>"US", :type=>"LOCAL", :numberPattern=>{:pattern=>"206", :search
Pattern=>:START}}, :url=>"https://numbers.api.sinch.com/v1/projects/{project_id}/availableNumbers:rentAny", :headers=>{}, :user=>"apikey", :password=>"secret"}
According to their documentation, these opts should mimic the CURL request that I mentioned above. But when I put it into the console:
> RestClient::Request.execute(opts)
Traceback (most recent call last):
1: from (irb):37
RestClient::BadRequest (400 Bad Request)
It's the same if I just request availableNumbers with the ":rentAny". I am very confused because it should work exactly the same vs using CURL.
09-06-2023 10:57 PM - edited 09-07-2023 12:20 AM
Also, it doesn't give a detailed error message if I catch the exception:
> begin
> RestClient::Request.execute(opts)
> rescue RestClient::BadRequest => e
> puts "e"
> end
e
=> nil
> e
=> #<RestClient::BadRequest: 400 Bad Request>
> puts e
400 Bad Request
=> nil
> e.default_message
=> "400 Bad Request"
> e.message
=> "400 Bad Request"
> e.original_exception
=> nil
> e.to_s
=> "400 Bad Request"
09-06-2023 11:21 PM - edited 09-06-2023 11:22 PM
Sorry I am actually able to get a clearer response if I type in
e.response.body: "invalid character 's' looking for beginning of value"
From what I've look into, it means that Sinch is not returning a valid response.
09-07-2023 12:18 AM
Hi
For whatever reason your payload is not valid. I would suspect the json payload is not properly formatted or you have some extra character included.
I recommend to intercept the outgoing HTTP request so you can validate the payload. You should be able to output the HTTP headers and request, then check the JSON payload is valid with jq.
09-07-2023 04:05 AM
Thank you for the response again, Roland!
I just copy/pasted every single key, value the apikey, secret, and endpoint from the failed Ruby rest-client request, into a curl request.
With all of the same exact data, it works on a CURL request, but not when using the rest-client on Ruby.
Maybe it has to do with the ":" colon? Because I actually just got the availableNumbers endpoint to work with the Ruby rest-client, but availableNumber:rentAny and availableNumber:rent aren't working. It seems that Ruby's rest client really just doesn't like something about these parameters, and I can't think of what else.
Regardless, "invalid character 's' looking for beginning of value" means that their response is not in a valid JSON format. From what I googled anyways.
09-07-2023 04:39 AM - edited 09-07-2023 04:42 AM
seriously, if I change the URL from:
"https://numbers.api.sinch.com/v1/projects/{project_id}/availableNumbers:rentAny" to just "https://numbers.api.sinch.com/v1/projects/{project_id}/availableNumbers?regionCode=US%type=LOCAL"
and the method from :post to :get
then run
RestClient::Request.execute(opts)
it works.
it's just not accepting when I change it to availableNumbers:rentAny. I've also tried to encode it as availableNumbers%3ArentAny, and that also did not work.
09-07-2023 05:20 AM
Hi
GET and POST are quite different in the fact that GET does not deliver a payload, it just retrieves data, but POST delivers a payload for parsing.
Please can you verify that the payload you send is well formatted json? I would recommend to open a ticket with SINCH support so they can look at the incoming payload for you if you are unable to do it 😀
09-07-2023 07:00 PM - edited 09-07-2023 07:02 PM
Hey Roland, thank you for the reply again! Yeah I know the difference between GET and POST 😄 I am a software developer lol.. The difference that I was pointing out, is that your GET availableNumbers was working fine, but you POST availableNumber:rentAny (which is a separate endpoint) was not working fine.
Anyways, I solved it! The payload needs to be JSONified. The rest client sends it as an object (vs CURL will send it as a JSON string) and the API only accepts the JSON string.
I'll write a detailed version in a minute, and I'll make that the answer here.