Testing a Web Feed with curl
After you've created a new Web Feed with a working Auto Importer, you can use the curl command-line utility to test the implementation by typing commands in a Terminal window.
The examples in this discussion assume the Auto Importer specification has
- recordUpdateMode="CREATE_AND_UPDATE to create a record if it doesn't exist or update fields if it does exist.
- inputType="JSON" to assumes the input data format is in JSON format.
The MS Windows command line doesn't always support single-quotes ('), and doesn't always handle double-quotes(") properly. When using curl on Windows, use double-quote instead of single quote, and escape intended double-quotes with a backslash.
Normal quotes:
-d '[{"responsedate":"2013-06-11 12:00:00", "lastname":"Test1", "firstname":"Test1", "property":"BLGE"}]'
Windows quotes:
-d "[{\"responsedate\":\"2013-06-11 12:00:00\", \"lastname\":\"Test1\", \"firstname\":\"Test1\", \"property\":\"BLGE\"}]"
Authorization
Authorization identifies what data the requester may access. Authorization is a process that complements authentication. Authorization happens in combination with permissions.
-
The application must have an account, see AppID Accounts for details.
The account's role must have the "Import Data via Webfeed" Admin Permissions set. For more information about permissions, see Administrative permissions and Data access permissions.
If you don't see the Admin Permissions shuttle box in Classic setup, add this permission through the Admin Suite role management tool instead.
Authentication
The web feed API uses OAuth to authentication the calling application. Applications pass a client ID and secret to the OAuth token endpoint to receive an access token. The applications then include that token in the HTTP header that posts data to the web feed API. For detailed information about getting a token and passing it to the API, see Authenticate APIs with OAuth.
This curl invocation authenticates and requests a bearer token from the endpoint. The client ID and secret are 'querydemo' and 'query12345':
curl https://queryapidemo.demo.sc4.medallia.com/oauth/fs/token -u 'querydemo:query12345' -d grant_type=client_credentials
The token request returns a string of text that is the access token. Include that token in all curl invocations with the -H 'Authorization: Bearer <token>' parameter, like this:
curl -H 'Authorization: Bearer bG8naW46dH9niW7zZWNgZXQ=' …
Traditionally the web feed accepted a username and password as the method of authentication. This method is deprecated, though not yet obsolete. For instances that still support this method, you can use the username method as follows.
In a production system, include the external system in the IP allow-list property on the Logon Restrictions screen (if it is being used), and the URL for accessing the Web Feed includes the Username property at the end of the URL (not the API endpoint), similar to this
https://xxx.medallia.com/company_name.feed?username
When using curl to test the Web Feed, omit the Username parameter, but include it and the Password property in the -u option, like this:
curl -u 'username:password' https://xxx.medallia.com/company_name.feed ...
Do not attempt to mix the two (do not include -u and the ?username) because the Web Feed will return an error: "Incorrect password".
API URL and endpoint
All web feeds for an instance post data to the same API via a URL that references the instance, like this:
https://instance.apis.medallia.com/inbound/v1/
Each web feed is identified by an endpoint whose name is unique to the web feed specification (as identified by the URL unique name parameter defined on the Web Feeds screen. The URL with endpoint looks like this:
https://instance.apis.medallia.com/inbound/v1/URL-unique-name
To post to the web feed, use the -X POST argument, like this:
curl -H 'Authorization: Bearer token' -X POST https://instance.apis.medallia.com/inbound/v1/URL-unique-name …
Submitting data using curl
To submit content with curl, use the -d option to either include the data in the command line, or to reference a filename that contains the data. This example submit inline JSON content:
curl -H 'Authorization: Bearer token' -X POST https://instance.apis.medallia.com/inbound/v1/URL-unique-name -d '[{"responsedate":"2013-06-11 12:00:00", "lastname":"Test1", "firstname":"Test1", "property":"BLGE"}]'
ok;1records,0duplicates,0rejects
Notice the last line above is the plain-text response from the Web Feed (Ok;1records,0duplicates,0rejects) To change the format of the response, use --header "Accept: <format>".
If anything goes wrong with the request such as malformed input data, you will likely to get a HTTP/1.1 400 Bad Request response. In that case, you will see an error message, like this:
curl -H 'Authorization: Bearer token' -X POST https://instance.apis.medallia.com/inbound/v1/URL-unique-name -d '[{"responsedate":"2013-06-11 12:00:00", "lastname":"Test1", "firstname":"Test1", "property":"BLGE"}]' --header "Content-Type: application/json" --header "Accept: application/json"
File processing error (Expected input columns [responsedate, gender, lastname, property, firstname], but found [responsedate, lastname, property, firstname]
To submit multiple records with JSON, include each record in braces ({}) and separate them with a comma, like this:
curl -H 'Authorization: Bearer token' -X POST https://instance.apis.medallia.com/inbound/v1/URL-unique-name -d '[{"responsedate":"2013-07-22 00:00:00", "lastname":"Test", "firstname":"Test", "property":"BLGE", "gender":"female"}, {"responsedate":"2013-07-22 00:00:00", "lastname":"Blah", "firstname":"Blah", "property":"BLGE", "gender":"male"}]' --header "Content-Type: application/json" --header "Accept: application/json"
{"records":1,"duplicates":0,"rejects":0}
To submit the contents as a file, reference the filename by starting the name with an @ symbol, like this:
curl -H 'Authorization: Bearer token' -X POST https://instance.apis.medallia.com/inbound/v1/URL-unique-name -d @datafile.json --header "Accept: application/json"
{"records":1,"duplicates":0,"rejects":0}
When submitting a binary file, use --data-binary instead. For example:
curl -H 'Authorization: Bearer token' -X POST https://instance.apis.medallia.com/inbound/v1/URL-unique-name --data-binary @excelfile.xls --header "Accept: application/json"
{"records":47,"duplicates":3,"rejects":2}
The Web Feed API passes the data to the Auto Importer specification, which attempts to determine the data format. However, it is better to specify the format with the HTTP Content-Type: header field. For example, to declare the data as JSON format:
curl -H 'Authorization: Bearer token' -X POST https://instance.apis.medallia.com/inbound/v1/URL-unique-name -d @datafile.json --header "Content-Type: application/json" --header "Accept: application/json"
{"records":1,"duplicates":1,"rejects":0}
The curl utility removes line-breaks from the file unless the data type is declared to be binary. When the file contains multiple lines, even if it is text, use the --data-binary option. For example, when uploading a text CSV file:
curl -u 'username:password' https://xxx.medallia.com/company_name.feed --data-binary @my_flat_file.csv --header "Accept: application/json"
{"records":47,"duplicates":3,"rejects":2}
Formatting the response
The Web Feed formats the response in plain text. You can tell the API to format the response in JSON, XML, or plain text with the Accept: field, like this:
curl -H 'Authorization: Bearer token' -X POST https://instance.apis.medallia.com/inbound/v1/URL-unique-name -d @datafile.json --header "Content-Type: application/json" --header "Accept: application/json"
{"records":1,"duplicates":0,"rejects":0}
Notice the response is a JSON element.
Verbose messaging
Sometimes you need to see the details of request and response. To do that with curl, include the -v option.
curl -v -H 'Authorization: Bearer token' -X POST https://instance.apis.medallia.com/inbound/v1/URL-unique-name -d '[{"responsedate":"2013-06-11 12:00:00", "lastname":"Test1", "firstname":"Test1", "property":"BLGE"}]'
* Trying 100.000.000.100...
* Connected to instance.apis.medallia.com (100.000.000.100) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server auth using Bearer
> POST /inbound/v1/URL-unique-name HTTP/1.1
> Host: instance.apis.medallia.com
> Authorization: Bearer bG8naW46dH9niW7zZWNgZXQ=
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Length: 97
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 15 out of 15 bytes
< HTTP/1.1 200 OK
< Server: nginx/1.11.1
< Date: Thu, 18 Aug 2016 20:35:26 GMT
< Content-Type: text/plain; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Strict-Transport-Security: max-age=31536000
< Access-Control-Allow-Origin: *
< Public-Key-Pins-Report-Only: max-age=3600; ...
<
ok; feed file created
* Connection #0 to host instance.apis.medallia.com left intact
