Shutterfly Open API  |  Call Signature


Overview

A Call Signature is a small set of extra parameters that your application calculates and appends to every Shutterfly Open API call, to digitally "sign" the call. Begin by obtaining a Shutterfly Open API application ID and shared secret.

The signature helps Shutterfly know that it has received the parameters you intended to send, including a timestamp. If you guard your "shared secret", the signature also provides MD5-level or SHA1-level protection against a third party forging calls in your app's name.

Signature generation can be tricky. For developers working in Java, Shutterfly supplies a library to make it easier.

An application signs each call by locally gathering and concatenating these pieces of data:

  1. the application's shared secret
  2. URL path (omitting the "http://hostname" part)
  3. URL parameters, if any
  4. these three parameters: app ID, hash method, and timestamp

The application then generates an MD5 or SHA1 digest of that "concatenated string". The digest becomes a fourth parameter, the call signature. The app then supplies app ID, hash method, timestamp and signature digest on its HTTP call. Notes:

  • Do NOT send the shared secret on your calls. Shared secret is needed only when your application generates the signature digest.
  • App ID must always be passed as an URL parameter.
  • Hash method, timestamp and signature digest may be passed as either additional URL parameters, or as HTTP request headers. Shutterfly will accept them as URL parameters, but recommends passing them as HTTP request headers instead - especially on Get calls - because that allows the Web to cache documents better.

Signature Generation Concepts

First, the application must gather its own values for the following three parameters:

oflyAppId
Type: String
Required: Yes
Example: 693228dc384ba239269fa6f80de8ce97
Description: Application ID
oflyHashMeth
Type: String
Required: Yes
Example: SHA1 -or- MD5
Description: The digest generation method (hash method) that the application is going to use when generating the app signature.
oflyTimestamp
Type: String
Required: Yes
Example: 2007-06-27T13:15:30.123-0700
Description: Current date and time, to the millisecond and formatted by the W3 profile of ISO 8601 (see http://www.w3.org/TR/NOTE-datetime). The indicated time must be within +/- 15 minutes of Shutterfly server time. For more details, see this document's Frequently Asked Questions.

Next, the app locally creates a string that concatenates these pieces, in order:

  1. your application's Shared Secret
  2. URI path for the specific API call. Include a leading slash; omit trailing slash. Example: /userid/000012345678
  3. A question mark.
  4. URL parameters for the API, if any, in alphabetical order. Notes:
    1. They must be in name=value form, separated by & (ampersand).
    2. "Alphabetical order" means alphabetical by parameter name, and in a case-sensitive manner (so that lowercase 'a' sorts after uppercase 'Z').
    3. The parameter values should not be "URL encoded" at this point - e.g., NOT substituting "%20" for blank, yet.
  5. Finally, the three parameters, as if they were additional URL parameters (i.e., name=value, with & as a separator). They must be in this order: oflyAppId, oflyHashMeth, oflyTimestamp.

Next, if building the above string on a Unicode system, take a UTF-8 encoded byte array of the concatenated string.

Next, take a message digest (a hash) of those bytes, using SHA1 or MD5 as previously chosen.

Finally, convert the hashed bytes to a hexadecimal string. The hex string is the signature. It will become the following parameter:

oflyApiSig
Type: String
Required: Yes
Example: f38366843e837d562ff6281ae150e386
Description: The generated call signature digest.

Your application now has values for all four Call Signature parameters - app ID, hash method, timestamp and signature digest. At this point, build your final URL and make the call. Notes:

  • When finally making your Shutterfly Open API call: URL parameters need not be in any special order.
  • Again, always put oflyAppId= as an URL parameter, and the other Call Signature parameters either as additional URL parameters or as HTTP request headers (recommended).
  • As a very last step, make sure the final URL is "URL encoded". (Substitute %20 for blank, %2B for plus sign, etc.)

Examples

Here is an example for the Authentication API. If there were no call signature, the developer would post to an URL like this:

https://ws.shutterfly.com/user/asdfasdf4@yahoo.com/auth
POST /user/asdfasdf4@yahoo.com/auth HTTP/1.1
Content-Type: [...]
Content-Length: [...]
[...]

To build the signature: Imagine the app ID is "91d6d14801815dda4be4982e9c0d39fa" and the shared secret is "5c2db08d7bd25c2e". The string built at step 2, above, should look like this (but all on one line):

5c2db08d7bd25c2e/user/asdfasdf4@yahoo.com/auth?oflyAppId=91d6d14801815dda4be4982e9c0d39fa
&oflyHashMeth=SHA1&oflyTimestamp=2007-07-02T11:28:36.776-0700

If the app sets HTTP headers for Call Signature, the final URL and headers look something like this:

https://ws.shutterfly.com/user/asdfasdf4@yahoo.com/auth?&oflyAppId=91d6d14801815dda4be4982e9c0d39fa
POST /user/asdfasdf4@yahoo.com/auth HTTP/1.1
Content-Type: [...]
Content-Length: [...]
oflyTimestamp: 2007-07-02T11:28:36.776-0700
oflyApiSig: 9a2910628acc54caeac6516acdf26f2171a2ab51
oflyHashMeth: SHA1
[...]

Note: in the app's final HTTP call, the order of URL parameters does not matter and the order of HTTP request headers does not matter.

If, instead, the app sets URL parameters for Call Signature, the final URL and headers look something like this (but the URL on one line):

https://ws.shutterfly.com/user/asdfasdf4@yahoo.com/auth?&oflyAppId=91d6d14801815dda4be4982e9c0d39fa
&oflyApiSig=9a2910628acc54caeac6516acdf26f2171a2ab51&oflyTimestamp=2007-07-02T11:28:36.776-0700
&oflyHashMeth=SHA1
POST /auth HTTP/1.1
Content-Type: [...]
Content-Length: [...]

Again, in the above, the order of URL parameters does not matter. And the POST body contains XML (not shown) as specified by the Authentication API document.

Here is another example, for creating a new Shutterfly member. If there were no call signature, the developer would post to an URL like this:

https://ws.shutterfly.com/user

To build the signature: Imagine the app ID is "91d6d14801815dda4be4982e9c0d39fa" and the shared secret is "5c2db08d7bd25c2e". The string built at step 2, above, should look like this (but all one line):

5c2db08d7bd25c2e/user?oflyAppId=91d6d14801815dda4be4982e9c0d39fa&oflyHashMeth=SHA1
&oflyTimestamp=2007-07-02T11:38:53.842-0700

If the app sets HTTP headers for Call Signature, the final URL and headers look something like this:

https://ws.shutterfly.com/user?oflyAppId=91d6d14801815dda4be4982e9c0d39fa
POST /user HTTP/1.1
[...]
oflyTimestamp: 2007-07-02T11:38:53.842-0700
oflyApiSig: 792c4e0a43ef00f9b23a0d8b7042030fbc8e9ddc
oflyHashMeth: SHA1
[...]

Note: in the app's final HTTP call, the order of URL parameters does not matter and the order of HTTP request headers does not matter.

If, instead, the app sets URL parameters for Call Signature, the final URL looks something like this (but all on one line):

https://ws.shutterfly.com/user?oflyAppId=91d6d14801815dda4be4982e9c0d39fa
&oflyApiSig=792c4e0a43ef00f9b23a0d8b7042030fbc8e9ddc&oflyTimestamp=2007-07-02T11:38:53.842-0700
&oflyHashMeth=SHA1

Again, in the above, the order of URL parameters does not matter. And the POST body contains XML (not shown) as specified by the Authentication API document.

Responses

All Shutterfly APIs return a common set of HTTP status codes. See Error Codes

API Explorer

You can test the correctness of your signature generation process with Shutterfly's API Explorer for Call Signature.

Frequently Asked Questions

General

My call gets an HTTP status code 400, "Bad request". What does that mean?
You tell us, as follows. When you get an HTTP 400, "Bad request", the response should additionally have a body whose content is a specific error message from Shutterfly; for example, "Bad timestamp". If you contact us for support, we will need to know this content, so please look for it.

Library Support

Does Shutterfly supply a library so I don't have to write my own call signature code?
Yes, provided that you are working in Java. Download one or more of the following: In the Javadoc, start by looking at com.shutterfly.openfly.raf.CallSignUtils: methods such as prepareOflyParms(), prepareSignedHttpConnection() or prepareSignedUri().

Timestamp

If I write my own call signature code: must I use Shutterfly's exact timestamp format?
Yes.
What is the format?
The format is YYYY-MM-DDThh:mm:ss.sssTZD, where:
YYYY=four-digit year
MM=two-digit month(01 through 12)
DD=two-digit day of month(01 through 31)
hh=two-digit hour(00 through 23; am/pm NOT allowed)
mm=two-digit minute(00 through 59)
ss=two-digit second(00 through 59)
sss=three-digit millisecond(000 through 999)
TZD=time zone designator(Z or +hh:mm or -hh:mm)

The following timestamps will cause different call signatures, but are all recognized as the same moment in universal time:

  • 2008-02-21T17:19:54.330-00:00
  • 2008-02-21T17:19:54.330Z
  • 2008-02-21T12:19:54.330-05:00
  • 2008-02-21T09:19:54.330-08:00
  • 2008-02-22T02:49:54.330+09:30

Because of the time zone designator, a timestamp represents a universal moment in time. The time zone designator is either the single character Z to indicate UTC (Coordinated Universal Time), or your time zone's offset from UTC described in hours and minutes.

Does the timestamp have to include milliseconds?
Yes. If your application can't obtain accurate milliseconds, supply 1-3 invented digits between 0 and 999 that will be likely to vary, if the same instance of your application repeats a call within the same second. For example, supply a sequence number or a random number.
Shutterfly responds that my timestamp is bad. What does that mean?
Your timestamp is wrong. It indicates a time that actually isn't within 15 minutes of current moment in the real world. Check your timestamp carefully, especially its timezone designator. Example: suppose you are in the U.S. Pacific time zone, and you had stated -08:00 with Pacific Standard Time in mind, but the real world has just shifted to Pacific Daylight Time, so your timezone designator now ought to be -09:00. Then your timestamp is incorrect. You can avoid such problems by always expressing times as -00:00, that is, as GMT / UTC. But even then, you could have a bad timestamp if your machine's clock is not set accurately.
What time zone are Shutterfly's servers in?
You don't need to know. Remember, these timestamps are universal moments in time. They have a "timezone designator" indicating their numeric offset from UTC. Make sure your machine's date and time are reasonably correct, and that your application generates a current timestamp in a correct format. Shutterfly will accept any correctly-formatted timestamp that describes a moment within +/- 15 minutes of universal time.
previous
Quick Start
next
User
Authentication
trust-e
© Copyright Shutterfly 1999-2008. All rights reserved.