[RESTful Web-service Documentation]
go top

RESTful Web-service Documentation

<rest image, don't delete block>

Stay connected with PantherMedia

If you like to implement functions of PantherMedia to your mobile, web or desktop application, you can do this via the "PantherMedia RESTful Web-service".

The API is available for non-commercial use by third-party developers. For downloading and/or showing images inside the app, please see our End User Licence Agreement. You require a prepaid account for downloading images.
For distribution partners or customers (e.g. integration of PantherMedia in you digital asset management system), please contact our sales team.
With the implementation of our REST service, you accept the API Terms of Use.

If you have any question, please send us each time the RAW request and a short description too.
Contact via Web-Form.

Get Started

  1. Get your API Key to register your App and to get access to our API. Get your Key here.
  2. Read and study the following documentation carefully.
If you're a developer who would like to publish a cool photo app with our images, everything you need to know to get started is right here.
Please keep us updated about your API integrations and apps. We will help you to push the best apps via our own marketing and social media channels.

The API is based on the REST technology. Therefore, it is programming language and platform independent.
The API consists of a set of methods that are based on a URL as an endpoint.
If you want to request a method, please send a request to its endpoint http://rest.panthermedia.net and specify a version, method and some arguments. Consequently, you will receive a response from our API.

Please specify the version via request header "Accept-Version" or via endpoint, e.g.: http://rest.panthermedia.net/v1.0/host-info

To get access, each request needs a minimum of the following 4 parameters:
Each method can have additional parameters as explained in this documentation.

The charset has to be UTF-8.


Please respect to limit your client requests to a maximum 3 requests per second. Otherwise we reserve the right to evaluate the inquiries as DDoS and to charge them for the incurred damage. Please see also "User-Agent" qualified string.

Additional things about REST you should know:

Method Call / Request

If you request an endpoint as HTTP GET, you will get back the documentation of the method.

For example, call http://rest.panthermedia.net/host-info in your web browser and you will see the documentation for the request "host-info".

If you like to get the documentation of a specified version, please include the version like this: http://rest.panthermedia.net/v1.0/host-info

The last supported version will be returned in the response header like: "X-API-Last-Version: 1.1", if a newer version as the called version exists. Future requests should still use the original URI if you don't intent to use the new version, but it is recommended to use the latest version, because deprecated versions could be removed without future announcement, see also HTTP Error 410 Gone.

To execute methods, please request the same endpoint with HTTP POST and the required version and parameters in an urlencoded format.

We recommend also to use "Accept-Encoding: gzip, deflate" if your used HTTP Client supports compression.

Sample RAW request:

POST http://rest.panthermedia.net/host-info
Accept-Version: 1.0
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded

api_key=a5e770dadd779347e0fdd4db91ad883d0592aaca031e2c81234f3cb8008fdd1f&access_key=96c35a3d110cf36709968972e38fb8e9879d656f&timestamp=Thu,%2026Jul%202012%2014:53:44%20UTC&nonce=Im%20ar%20andomS%20tring&algo=sha1

Or

POST http://rest.panthermedia.net/v1.0/host-info
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded

api_key=a5e770dadd779347e0fdd4db91ad883d0592aaca031e2c81234f3cb8008fdd1f&access_key=96c35a3d110cf36709968972e38fb8e9879d656f&timestamp=Thu,%2026Jul%202012%2014:53:44%20UTC&nonce=Im%20ar%20andomS%20tring&algo=sha1

Most methods allow you to request the endpoint as HTTP GET too, but we recommend to use HTTP POST as default.


Requests in REST can be sent or executed in many different ways depending on the programming language.
The easiest way in Perl and PHP is to use "libcurl", but you can also use Toolkits or Frameworks like: Zend_Rest_Client, crVCL PHP Framework for PHP or for example in Java JAX-RS

A good tool to test the REST web-services in Firefox is the Add-on RESTClient or POSTMAN API Client. For Windows OS you can use I'm Only Resting

For debugging, you can also use the PantherMedia REST Developer Tools.


Screenshot HttpRequester

HttpRequester

Response

The response is a simple XML based on the REST standard:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rsp stat="ok">
[xml-payload-here]
</rsp>

XML RAW response:
  Status Code: 200 OK
Cache-Control: no-store, no-cache, max-age=0, must-revalidate, post-check=0, pre-check=0
Connection: close
Content-Type: text/xml;charset=UTF-8
Date: Wed, 25 Jun 2014 08:19:01 GMT
Expires: Thu, 1 Jan 1970 00:00:00 GMT
Pragma: no-cache
X-API-Version: v1.0
X-API-Last-Version: v1.1


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rsp stat="ok">
[xml-payload-here]
</rsp>


All responses can be returned e.g. as JSON. To return the response as JSON, please pass the argument "content_type" with the value "application/json"

JSON RAW response:
  Status Code: 200 OK
Cache-Control: no-store, no-cache, max-age=0, must-revalidate, post-check=0, pre-check=0
Connection: close
Content-Type: application/json
Date: Wed, 25 Jun 2014 08:19:01 GMT
Expires: Thu, 1 Jan 1970 00:00:00 GMT
Pragma: no-cache
X-API-Version: v1.0
X-API-Last-Version: v1.1


{
 "stat": "ok",
 [json-payload-here]
}



REST requires the use of HTTP error-handling.
If an error occurs, the API returns an HTTP error.

Depending on the severity of the error, it returns the content of the response as a simple "text/html" on fatal errors, or "text/xml" ("application/json") on normal errors.

RAW html content:
400 Bad request
Date:  Fri, 27 Jul 2012 13:45:10 GMT
Server:  Apache/2.2.16
Expires:  Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control:  no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma:  no-cache
Status:  400 Bad request
Connection:  close
Vary:  Accept-Encoding
Content-Encoding:  gzip
Content-Length:  88
Content-Type:  text/html

400 Bad request (algorithm not supported, Supported Algos: sha1 - sha256 - sha512)

RAW xml content:

401 Unauthorized
Date:  Fri, 27 Jul 2012 13:58:28 GMT
Server:  Apache/2.2.16
Expires:  Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control:  no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma:  no-cache
Status:  401 Unauthorized
Connection:  close
Vary:  Accept-Encoding
Content-Encoding:  gzip
Content-Type:  text/xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rsp stat="fail">
<err code="401" msg="access denied">
</err>
</rsp>

Error-Codes

200 OK

Standard response for successful requests.

400 Bad Request

The request cannot be fulfilled due to bad syntax, as sample missing required parameter or wrong type of parameter.

401 Unauthorized

Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided. Your app not grant the permission to access this user resource or the auth token or access token passed was not valid or maybe expired.

402 Payment Required

The request was a valid request, but the server is refusing because the account have not enough deposit for the called request.

403 Forbidden

The request was a valid request, but the server is refusing to respond to it. Your app not grant the permission to access this service, maybe the api key or access key passed was not valid or "User-Agent" is missing. It is also possible that the Web Application Firewall blocks you temporary due to many requests.

404 Not Found

The requested resource (media) could not be found but may be available again in the future. Subsequent requests by the client are permissible.

410 Gone

Indicates that the resource (media) requested is no longer available and will not be available again. (old deprecated api version there are no longer available).

412 Precondition Failed

If you send a request with missing header informations like "User-Agent".

Please use for "User-Agent" a qualified string like

[YourClient] / [YourAppName],

for example:
"RestSharp / 106.6.10.0 / MyStockImageApp"



Or even better would be to pass the referer too, but this is optional.

[YourClient] / [YourAppName] / [RefererUser-Agent],

Example 1:
"RestSharp / 106.6.10.0 / MyStockImageApp / Mozilla/5.0 (compatible; Googlebot / 2.1; + http: //www.google.com/bot.html)"

Example 2:
"RestSharp / 106.6.10.0 / MyStockImageApp / Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0"

So we can also guarantee that a bot on our side will not break any rate limits.

419 Authentication Timeout

for example if a valid authentication (token) has expired.

421 There are too many connections from your internet address

Too many requests in a given amount of time from the same IP address.

423 Locked

User locked by PantherMedia as sample due legal reasons.

429 Too Many Requests

The client has sent too many requests in a given amount of time.

501 Not Implemented

The server either does not recognize the request method.

500 Internal Server Error

A generic error message, given when no more specific message is suitable, in this case please open a support request on PantherMedia.

503 Service Unavailable

This server error response code indicates that the server is not ready to handle the request. Common causes are, that the server is down for maintenance.
If the Retry-After HTTP header is present, it estimated the time for the recovery of the service.

506 Variant Also Varies

You can try to fetch the request again with the parameter "dont_validate_content=true" and/or open a support request on PantherMedia.


This is only a small overview of the most important HTTP error codes in the API, but all other standard HTTP error codes also apply

App-Authentication

Each method requires the authentication via "api_key" (alias "consumer_key") to secure incoming requests.
For most requests work HTTP and HTTPS, except the method "request-token" as sample. This request is only allowed via HTTPS. Due to privacy reasons, we recommend to send all requests via HTTPS and use HTTP only for debugging.

To authenticate a request, please pass your "api_key" in combination with "access_key", "timestamp" and "nonce" String.

api_key => you get it in your PantherMedia account, see Get Started
timestamp => UTC formated DateTime like "Thu, 26 Jul 2012 14:53:44 UTC",  the timestamp must be within a reasonable tolerance of +/- 5 minutes.
nonce => random character string for security
access_key => hash-based message authentication code (HMAC) of the timestamp followed by the api_key and nonce encrypted by your api secret (consumer secret). The default algorithm for the HMAC is sha1, by passing the parameter algo you can use  sha256 or sha512 as a sample for a higher security instead.

PHP Sample:

function str_random($len = 8, $allowed_charset=null) {
        if($allowed_charset === null){
           $allowed_charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        }
        return substr(str_shuffle($allowed_charset), 0, $len);
}

$api_secret = 'd779ff347e0ca031e2c';
$timestamp = str_replace('+0000','UTC', gmdate(DATE_RSS));
$api_key = 'a5e770dadd779347e0fdd4db91ad883d0592aaca031e2c81234f3cb8008fdd1f';
$nonce = str_random();

$data = $timestamp.$api_key.$nonce;
$access_key = hash_hmac('sha1', $data, $api_secret);


RAW response, if you use a wrong api key / access key:

403 Forbidden
Date:  Tue, 31 Jul 2012 11:42:57 GMT
Server:  Apache/2.2.16
Expires:  Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control:  no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma:  no-cache
Status:  403 Forbidden
Connection:  close
Vary:  Accept-Encoding
Content-Encoding:  gzip
Content-Length:  61
Content-Type:  text/html
403 Forbidden (invalid api or access key)

User-Authentication

Some methods require the user to be signed in. PantherMedia is its own authorization service provider. 
The authentication is based on the OAuth  / RFC 2617 specification which is the industry standard and works like on Flickr, Google, Amazon, Facebook and Twitter.
It will provide a secure way for people to sign-in into their PantherMedia account within your application.
The authentication flow works for web-applications, desktop apps and mobile applications as well.
For more info, see request-token.

Authentication Flow

To authenticate a request that needs to get user data, please pass the App authentication and the authorized "auth_token" in combination with "access_token", "timestamp" and "nonce" String.
Hashing the "access_token" is similar to hashing an "access_key".

auth_token => the authorized token requested by your App and authorized by the User
timestamp => UTC formated DateTime like "Thu, 26 Jul 2012 14:53:44 UTC",  the timestamp must be within a reasonable tolerance of +/- 5 minutes.
nonce => random character string
access_token => hash-based message authentication code (HMAC) of the timestamp followed by the auth_token and nonce encrypted by your token secret. The default algorithm for the HMAC is sha1, by passing the parameter algo you can use sha256 or sha512 for a higher security as sample instead.

PHP Sample:

$token_secret = 'MySecret';
$auth_token = '5e770c81234f3cb8008fdd1fdad883d0592aaca031e2';

$data = $timestamp.$auth_token.$nonce;
$access_token = hash_hmac('sha1', $data, $token_secret);


Each "auth_token" is valid for 10 minutes by default (for fresh new tokens). If a request requires an authentication (and the token is commited by the ressource owner) that is valid less than 30 minutes, this authentication will be extended by 60 additional minutes. If you like, you can increase the validity up to 90 days - this should be also renewed from time to time by your App, but for security reasons it is better the token outdated and the user must commit a new one.

For more info, see token-valid-until.


RAW response, if the "auth_token" of the requested resource owner is not authorized or expired - in this case your App should pass the authentication work flow again:
  401 Unauthorized
Date:  Fri, 27 Jul 2012 13:58:28 GMT
Server:  Apache/2.2.16
Expires:  Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control:  no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma:  no-cache
Status:  401 Unauthorized
Connection:  close
Vary:  Accept-Encoding
Content-Encoding:  gzip
Content-Type:  text/xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rsp stat="fail">
<err code="401" msg="access denied">
</err>
</rsp>

OAuth 1.0 for App/User Authentication 

Instead of the default App and User Authentication, you can also use OAuth 1.0 to authorize a request. This is more complex, but also more secure.
If you use OAuth 1.0, then the authentication is sent via HTTP header instead of HTTP parameter.
A base string of the request containing the HTTP method in combination with the endpoint and all GET/POST parameters supplemented by the oauth_* parameter will be hashed to a signature.
OAuth is supported by many standard libraries of modern programming languages.

Sample OAuth 1.0 RAW request for Consumer Authentication:

POST http://rest.panthermedia.net/host-info
Accept-Version: 1.0
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth oauth_version="1.0",oauth_consumer_key="myconsumerkey",oauth_timestamp="1414675641",oauth_nonce="1TyWAxxTB62",oauth_signature_method="HMAC-SHA1",oauth_signature="i86MF7x5bIMeWpca1%2Fm6cGcaors%3D"


Sample OAuth 1.0 RAW request for Consumer and Resource Owner Authentication:
POST http://rest.panthermedia.net/host-info
Accept-Version: 1.0
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth oauth_version="1.0",oauth_consumer_key="myconsumerkey",oauth_token="mytoken",oauth_timestamp="1414675641",oauth_nonce="1TyWAxxTB62",oauth_signature_method="HMAC-SHA1",oauth_signature="WyGboe%2BiGDYQxVII0iC%2B1s4l%2BDE%3D"