Unable to accept songs submitted to moderated group via SoundCloud API - soundcloud

I'm getting 404 when hitting url like this, (offc. with variables changed to proper values):
PUT https://api.soundcloud.com/groups/<group_id>/pending_tracks/<track_id>
Calling DELETE on that same URL works as expected, it rejects submission from group.
Requesting simple GET .../pending_tracks (no track-id at the end) works fine for me.
The tools I have used so far to test this are:
official PHP library (by mptre),
manually constructed cURL request,
cURL binary on windows
I couldn't find any info in SoundCloud API docs (or on the internet) how this API method should or could be used. Any chance someone could help me with how it is supposed to be accessed properly, these are the questions:
what is the correct url
if there should be any, what is expected as the query data
if there a query body and what is the format.
More details:
Calling PUT /groups/44/pending_tracks/99119291 returns 404, so I've figured
out, the track ID must be supplied some other way.
By digging trough the PHP wrapper and gathering pieces of info scattered
around the internet, I've found out that some PUT requests are complemented
with CURLOPT_POSTFIELDS and other have XML in their body. So far I went with
postfields approach.
My curl binary config looks like this:
--url https://api.soundcloud.com/groups/44/pending_tracks
--cacert cacert.pem
--user-agent PHP-SoundCloud
--header "Accept: application/json"
--header "Authorization: OAuth XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
--request PUT
--data <!--read on please-->
The data section was tested with following strings, each time supplying as
a value track-id like this track[id]=99119291:
track
track[]
track[id]
track-id
track_id
trackid
approve
approved
approve[]
approve[tracks][]
approved[tracks][]
tracks[approve][]
tracks[approved][]
approve[tracks][][id]
approved[tracks][][id]
tracks[approve][][id]
tracks[approved][][id]
tracks[]
tracks[][id]
tracks[][track][id]
tracks[][track][][id]
group[][id]
group[approve][]
group[approve][id]
group[approve][][id]
group[approved][]
group[approved][id]
group[approved][][id]
group[track][approve]
group[track][approve][]
group[track][approved][]
group[track][approve][id]
group[track][approve][][id]
group[track][approved][][id]
group[track][id]
group[tracks][id]
group[track][][id]
group[tracks][][id]
group[tracks][]
groups[][id]
groups[approve][id]
groups[approve][][id]
groups[approved][id]
groups[approved][][id]
groups[track][approve]
groups[track][approve][]
groups[track][approved][]
groups[track][approve][id]
groups[track][approve][][id]
groups[track][approved][][id]
groups[track][id]
groups[tracks][id]
groups[track][][id]
groups[tracks][][id]
Needless to say, none of those worked, each time result was the same as if I was accessing API endpoint with a simple GET request.
I'm really tired of blindly poking the SoundCloud API.

I'm sorry for you pain with the API, I fully agree it deserves a lot more and better documentation.
Anyway, while it's unclear to me why it got implemented like this, you should be able to approve tracks by sending a PUT request to api.soundcloud.com/groups/:group_id/tracks/:track_id. I hope that helps.

Related

"Missing Authentication Token" Error when calling DVLA MOT history API with Postman

Note - I am very much new to all this. Apologies if anything is unclear.
My overriding aim is to pull out MOT history data for a large batch of vehicles from the DVLA API. I understand that this can be done using Postman, which I am using (on a 64-bit Windows laptop if at all relevant).
The DVLA provide the following instructions
====================================================
Getting started
All API interfaces are implemented as restful APIs and accessed over https.
To access API you will need an API key that uniquely identifies the source of the request. DVSA will give you an API key if it approves your application.
You should keep your API key secure, as DVSA manages throttling and quotas at an API key level.
Each request must have the following mandatory fields in the header:
Accept: application/json+v6
x-api-key:
Content-type field confirms that the response type is in JSON format, and the x-api-key field serves your API key to identify the source of the request.
Technical resources
Access the API at https://beta.check-mot.service.gov.uk/
This root URL will change when the service moves from beta to live.
These 4 endpoints equate to the 4 methods of using the API:
/trade/vehicles/mot-tests?registration={registration}
‘Registration’ is the vehicle registration number.
===================================================
In order to test that this is possible, I am entering the following single request into the bar in Postman, selecting "POST" and hitting "SEND"
https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests?Content-type=application/json&x-api-key=ABCDEFGH&registration=MYREG
n.b. no inverted commas or other punctuation surrounds the actual values for ABCDEFH or MYREG
Expected result: Some sort of JSON with MOT history for this vehicle
Actual result: {"message": "Missing Authentication Token"}{"message": "Missing Authentication Token"}
I am unclear on:
- whether I should be using POST
what the +v6 after the application is necessary (other documentation leaves it out)
Why "Accept" and "Content-type" appear to be used interchangeably in the documentation
Whether the ordering of the parameters matters
Whether this can be equally tested by simply pasting the url into a browser
Thanks for any help
Reading through the Documentation found here:
https://dvsa.github.io/mot-history-api-documentation/
It mentions that those fields should be added as Headers:
Each request must have the following mandatory fields in
the header:
- Accept: application/json+v6
- x-api-key: <your api key>
There are example cURL requests on the site to help you with creating the request.
If you use Postman's Import feature within the app (found in the top right), you can add this cURL request in the Paste Raw Text tab.
curl -H "Accept: application/json+v6" -H "x-api-key: <your_api_key>" https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests\?registration=ZZ99ABC
This will give you an example request of what it should look like. From here, you will be able to add in your own API Token and send the request.
If you are using Postman, you can use the Authorization tab right under the request to give the required mandatory header fields. Select Header from Add to drop down. You can also add additional headers information using the next tab named Headers. (for example, the accept-headers).
Edit:
Authorization:
Headers Tab
Normally, you should be getting the authorization token when you register to the site in question(x-api-key here).You need to figure out the value of that token from the initial call's response headers. According to the document which Danny shared, you will be getting x-api-key from them once they approve your request.
Edit:
Alternatively, you can use import feature as Danny suggested in his answer. At the end of the day, you need to add the values as headers instead of query parameters.
For anyone using Python with the MOT history api and getting the same error message, try GET:
import requests
url = f'https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests?registration={plate_number}'
payload = {}
headers = {
'Accept': 'application/json+v6',
'x-api-key': 'your-api-key'}
response = requests.get(url, headers=headers, data=payload)
data = response.json()
model = data[0]['model'] # get the vehicle model for example
print(model)

Dream factory call REST API and character parameter

Currently, I have a problem with Dream Factory REST API call, when a space is present into the API URL call.
I have a get request with a sort parameter that must to be send for SOLR server. This space I don’t know how it is converted, but it seems to arrive into not appropriate mananer.
curl -X GET
‘http://localhosts:81/api/v2/test/list/test?rows=10&sort=random_test%20desc’
-H ‘X-DreamFactory-Api-Key: e115f92d18ba58e9a29389’
-H ‘X-DreamFactory-Session-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1’
SOLR need to have this sort parameter and the direction of the sort. So we provide the column to sort, space and the direction. When I execute this curl using Dream Factory api, then the space or the %20 character seems to be converted into other thing.
Is there someone knowing, if this is a Dream factory problem, or whether it is possible to make the call in another manner?
Finaly the solution that I found is to change the curl call in order to make POST request and to put the parameters with spaces into the -d parameter.
Here is the call working for our case :
curl -X POST \
'http://localhost:81/api/v2/test/list/test?rows=10' \
-H 'X-DreamFactory-Api-Key: e115f92d18ba58e9a2' \
-H 'X-DreamFactory-Session-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJz' \
-d 'sort=random_test+DESC&fq=NAME:*ov*+OR+NAME:*a*'

SoftLayer Rest API attachDiskImage call throwing error

I am trying with the below one it always throws "You must provide a valid portable storage volume id.". I have replaced my virtualGuestId,imageId,user name and apikey in below curl.
curl "https://[username]:[apiKey]#api.softlayer.com/rest/v3/SoftLayer_Virtual_Guest/[virtualGuestId]/attachDiskImage.json?imageId=[imageId]"
Please let me know the correct API to use to load an disk image and how to fetch the details of disk image.
I recomend you to take a look at these links:
https://sldn.softlayer.com/blog/bpotter/more-softlayer-rest-api-examples
https://sldn.softlayer.com/article/REST
Well the method attachDiskImage has as parameters the "imageId" of the portable storage as you can see in documentation:
http://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest/attachDiskImage
The parameters must be sent using the POST method and you need to send those parameters in a payload with a JSON format, so your request should be changed to this one:
curl -X POST -d '{"parameters":[$IMAGEID]}' https://$SLUSERNAME:$SLAPIKEY#api.softlayer.com/rest/v3/SoftLayer_Virtual_Guest/$VIRTUALGUESTID/attachDiskImage.json
Note: replace $IMAGEID, $SLUSERNAME, $SLAPIKEY and $VIRTUALGUESTID
Regards

BigCommerce API Update Order with PUT

I need to update an order which is done via PUT method passing the order id as part of the https url string and a single parameter, the status_id.
https://mystore.mybigcommerce.com/orders/12345.json
I have tried several methods to pass the status_id value but no matter what I try "status_id=12" or formatted as JSON "{"status_id": 12,}" I always get the same response:
[{"status":415,"message":"The specified input content type is not valid."}]
I have also tried as a POST request passing the JSON or XML code as raw data but that method is not supported.
How am I supposed to pass that field=value pair? can I embed it in the url string?
I also tried it but it wouldn't work for me.
Any ideas?
In case you are wondering I am doing it within FileMaker with TROIUrl plugIn, not a very popular technology, but the GET method retrieving orders works like a charm
TURL_Put( ""; $url ;"status_id=12") (I have also tried other FM plugIns to no avail)
Don't get too caught up in the Filemaker part, I don't expect many people out there to be familiar with BigCommerce and Filemaker. I just need a generic answer.
Thanks
Commandline tool curl is worth a try. It supports put and https.
Mac OS X: curl already installed, call from FileMaker via AppleScript do shell script.
Windows: must be installed, call via Powershell.
It works for me using { "status_id": "3" } which means you probably need to put quotes around the actual number.
Also, it is a PUT operation and application/json which is part of the request content.
The error message received by the OP:
[{"status":415,"message":"The specified input content type is not valid."}]
Is saying that he did not supply the 'Content-Type' header in his request or that the header supplied is for a content type that is not allowed. For the OP's case using JSON he would need to include the header:
Content-Type: application/json
in his HTTPS request. This description can be found along with those of the other status codes you may see here:
https://developer.bigcommerce.com/api/status-codes

Restful way for deleting a bunch of items

In wiki article for REST
it is indicated that if you use http://example.com/resources DELETE, that means you are deleting the entire collection.
If you use http://example.com/resources/7HOU57Y DELETE, that means you are deleting that element.
I am doing a WEBSITE, note NOT WEB SERVICE.
I have a list that has 1 checkbox for each item on the list. Once i select multiple items for deletion, i will allow users to press a button called DELETE SELECTION. If user presses the button, a js dialog box will popup asking user to confirm the deletion. if user confirms, all the items are deleted.
So how should i cater for deleting multiple items in a RESTFUL way?
NOTE, currently for DELETE in a webpage, what i do is i use FORM tag with POST as action but include a _method with the value DELETE since this is what was indicated by others in SO on how to do RESTful delete for webpage.
One option is to create a delete "transaction". So you POST to something like http://example.com/resources/deletes a new resource consisting of a list of resources to be deleted. Then in your application you just do the delete. When you do the post you should return a location of your created transaction e.g., http://example.com/resources/deletes/DF4XY7. A GET on this could return the status of the transaction (complete or in progress) and/or a list of resources to be deleted.
I think rojoca's answer is the best so far. A slight variation might be, to do away with the javascript confirm on the same page, and instead, create the selection and redirect to it, showing a confirm message on that page. In other words:
From:
http://example.com/resources/
do a
POST with a selection of the ID's to:
http://example.com/resources/selections
which, if successful, should respond with:
HTTP/1.1 201 created, and a Location header to:
http://example.com/resources/selections/DF4XY7
On this page you will then see a (javascript) confirm box, which if you confirm will do a request of:
DELETE http://example.com/resources/selections/DF4XY7
which, if successful, should respond with:
HTTP/1.1 200 Ok (or whatever is appropriate for a successful delete)
Here's what Amazon did with their S3 REST API.
Individual delete request:
DELETE /ObjectName HTTP/1.1
Host: BucketName.s3.amazonaws.com
Date: date
Content-Length: length
Authorization: authorization string (see Authenticating Requests (AWS Signature Version 4))
Multi-Object Delete request:
POST /?delete HTTP/1.1
Host: bucketname.s3.amazonaws.com
Authorization: authorization string
Content-Length: Size
Content-MD5: MD5
<?xml version="1.0" encoding="UTF-8"?>
<Delete>
<Quiet>true</Quiet>
<Object>
<Key>Key</Key>
<VersionId>VersionId</VersionId>
</Object>
<Object>
<Key>Key</Key>
</Object>
...
</Delete>
But Facebook Graph API, Parse Server REST API and Google Drive REST API go even further by enabling you to "batch" individual operations in one request.
Here's an example from Parse Server.
Individual delete request:
curl -X DELETE \
-H "X-Parse-Application-Id: ${APPLICATION_ID}" \
-H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
https://api.parse.com/1/classes/GameScore/Ed1nuqPvcm
Batch request:
curl -X POST \
-H "X-Parse-Application-Id: ${APPLICATION_ID}" \
-H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"requests": [
{
"method": "POST",
"path": "/1/classes/GameScore",
"body": {
"score": 1337,
"playerName": "Sean Plott"
}
},
{
"method": "POST",
"path": "/1/classes/GameScore",
"body": {
"score": 1338,
"playerName": "ZeroCool"
}
}
]
}' \
https://api.parse.com/1/batch
Interestingly, i think the same method applies as to PATCHing multiple entities, and requires thinking about what we mean with our URL, parameters and REST method.
return all 'foo' elements:
[GET] api/foo
return 'foo' elements with filtering for specific ids:
[GET] api/foo?ids=3,5,9
Wherein the sense is the URL and the filter determine "what elements we are dealing with?", and the REST method (in this case "GET") says "what to do with those elements?"
Hence PATCH multiple records to mark them as read
[PATCH] api/foo?ids=3,5,9
..with the data foo[read]=1
Finally to delete multiple records, this endpoint is most logical:
[DELETE] api/foo?ids=3,5,9
Please understand I don't believe there are any "rules" on this - to me it just "makes sense"
I would say DELETE http://example.com/resources/id1,id2,id3,id4 or DELETE http://example.com/resources/id1+id2+id3+id4. As "REST is an architecture (...) [not] protocol" to quote this wikipedia article there is, I believe, no single one way of doing this.
I am aware that above is not possible without JS with HTML but I get the feeling that REST was:
Created without thinking of minor details like transactions. Who would need to operate on more then single item? This is somehow justified in HTTP protocol as it was not intended to serve through it anything else other then static webpages.
Not necessary well adjusting into current models - even of pure HTML.
As Decent Dabbler answer and rojocas answer says, the most canonical is using virtual resources to delete a selection of resources, but I think that is incorrect from a REST perspective, because executing a DELETE http://example.com/resources/selections/DF4XY7 should remove the selection resource itself, not the selected resources.
Taking the Maciej Piechotka anwser or the fezfox answer, I only have an objection: There's a more canonical way of pass an array of ids, and is using the array operator:
DELETE /api/resources?ids[]=1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d&ids[]=7e8f9a0b-1c2d-3e4f-5a6b-7c8d9e0f1a2b
In this way you are attacking to the Delete Collection endpoint but filtering the deletion with a querystring in the right way.
I had the same situation to delete multiple items. This is what I ended up doing. I used DELETE operation and the ids of items which were to be deleted were part of HTTP header.
As there is no 'proper' way to do this, what I have done in the past is:
send DELETE to http://example.com/something with xml or json encoded data in the body.
when you receive the request, check for DELETE, if true, then read the body for the ones to be deleted.