Docs

Ospry is the simplest way for developers to host their images. Ospry removes the configuration overhead of generic storage solutions like S3, and provides additional tools to make handling images a breeze.

With Ospry, developers get reliable cloud storage, world-class CDN acceleration, image-level privacy settings, and a growing number of real-time rendering capabilities in a single service.

Simple uploads. Faster downloads. Rendering on-the-fly.

Get started below, and let us know what you think. We’re always happy to answer questions at support@ospry.io.

Getting started

Sign up for an account

To get started with Ospry, sign up for an account. Your first 1,000 images and 1 GB of monthly download bandwidth are free.

Sign Up

Grab the JavaScript library

Include the latest version of Ospry’s JavaScript library.

<script src="https://code.ospry.io/v1/ospry.js"></script>

Start uploading

Here's an example image resizing service. Simply call ospry.up() to store the image, then use ospry.get() to render the image at a new size:

<form id="up-form">
  <input type="file" multiple />
  <button type="submit">Upload</button>
</form>
// Note: This example uses JQuery, but it is not required to use Ospry

var ospry = new Ospry('YOUR_PUBLIC_API_KEY');

var onUpload = function(err, metadata) {
  ospry.get({
    url: metadata.url,
    maxHeight: 400,
    imageReady: function(err, domImage) {
      $('body').append(domImage);          
    },
  });
};

$('#up-form').submit(function(e) {
  e.preventDefault();
  ospry.up({
    form: this,
    imageReady: onUpload,
  });
});

In a few lines of code, you've taken care of cross-browser uploads, cloud storage, resizing, and CDN integration!

How it Works

Image Upload

The upload flow lets developers make cross-browser uploads directly to Ospry's cloud storage. When an image is successfully uploaded, Ospry sends back metadata about the image. The metadata can be used immediately (as in the Getting Started example), or sent up to your own server for future use.

Developers can optionally verify an image upload by "claiming" it server-side with their secret API key. Image claiming is covered in full detail here.

Image Download

Developers can retrieve or re-render images by passing the image's URL to the client, and calling ospry.get(). If the URL points to a private image, the URL must be signed server-side with the secret API key. ospry.get() allows the developer to specify particular rendering options, such as image format and size. Public images are cached in the CDN, ensuring your users always get their content fast.

Learn more about privacy controls and url-signing

JavaScript

Ospry's client-side JavaScript library allows developers to upload images across all browsers, IE 8 and above. The interface has two primary methods: ospry.up() for uploads, and ospry.get() for downloads.

Including the JS

Include the latest version of Ospry’s JavaScript library. Copy and paste the following script tag just before your closing </body> tag:

<script src="https://code.ospry.io/v1/ospry.js"></script>

Initialization

Before you can upload or download images, you need to initialize Ospry. Create a new Ospry instance, passing in your public API key.

var ospry = new Ospry('YOUR_PUBLIC_API_KEY');

Every Ospry account comes with a set of "test" and "production" API keys. Make sure you're using the right ones! A good way to manage this would be to use a templating language, and have your server fill-in the right key.

up

Uploads one or more image files to Ospry for storage. If you need compatibility with older browsers, you must provide a form.

ospry.up({
  form:       // DOM Element
  files:      // FileList
  isPrivate:  // Boolean
  imageReady: // Function
  done:       // Function
})

Options

form:
HTMLFormElement

A form element containing at least one file input. Any files attached to the file input will be uploaded.

files:
FileList

A list of image files to be uploaded. Taken from input.files or a drag-n-drop payload.

isPrivate:
boolean

Flag indicating whether an image is private. (Defaults to public)

imageReady:
Function (err, metadata, index)

Called once for each image when its upload attempt is complete or has failed. See callbacks: imageReady

done:
Function ()

Called once all images have completed an upload attempt.
See callbacks:done

Callbacks

imageReady:
(err, metadata, index)

Called once for each image when its upload attempt is complete or has failed. Each image will receive this callback exactly once. If the upload has completed successfully, err will be null.

Arguments

err: Ospry Error object (see errors)

metadata:

{
  id:          // {string}  Ospry image ID
  url:         // {string}  Ospry download URL
  httpsURL:    // {string}  Download URL if your site is served over HTTPS
  timeCreated: // {Date}    Image upload time
  isClaimed:   // {boolean} Whether the image upload has been verified
  isPrivate:   // {boolean} Whether the image is private
  filename:    // {string}  Image filename
  format:      // {string}  Image format (e.g. "jpeg")
  size:        // {number}  Image file size in bytes
  height:      // {number}  Image height in pixels
  width:       // {number}  Image width in pixels
}

index: Index of the image in the provided group of files. If there is only one file being uploaded, this will be 0. Useful for managing UI.

done:
()

Called once all images have completed an upload attempt. No imageReady callbacks will be fired after this is called.

Example Usage

<form id="up-form">
  <input type="file" multiple />
  <button type="submit">Upload<button>
</form>
$('#up-form').submit(function(e) {
  e.preventDefault();
  ospry.up({
    form: this,
    imageReady: function(err, metadata, i) {
      if (err === null) {
        console.log('Image uploaded to: ' + metadata.url);
      }
    },
  });
});

get

Downloads one or more images from Ospry, using the specified rendering parameters.

ospry.get({
  url:        // String
  urls:       // Array[String}
  format:     // String
  maxWidth:   // Number
  maxHeight:  // Number
  preload:    // Boolean (Defaults to true)
  imageReady: // Function
  done:       // Function
})

Options

url:
string

The Ospry download URL for a single image. If the image is private, this must be a signed URL.

urls:
Array[string]

A list of Ospry download URLs. If any of the images are private, the corresponding urls must be signed.

format:
string

The desired image format. Allowable values are: 'jpeg', 'png', and 'gif'.

maxHeight:
number

The desired maximum height, in pixels, of the downloaded image. If the original image size has a smaller height, the downloaded image will remain the original size.

maxWidth:
number

The desired maximum width, in pixels, of the downloaded image. If the original image size has a smaller width, the downloaded image will remain the original size.

preload:
boolean

Whether or not the DOM Image should be fully loaded before callbacks:imageReady is called. Defaults to true. Preloading is a UI convenience that allows you to reliably start associated animations or transitions without worrying whether the image is still loading on-screen.

imageReady:
Function (err, domImage, index)

Called for each image when its download attempt is complete or has failed. See callbacks: imageReady

done:
Function ()

Called once all images have completed a download attempt.
See callbacks:done

Callbacks

imageReady:
(err, domImage, index)

Called once for each image when its upload attempt is complete or has failed. Each image will receive this callback exactly once. If the upload has completed successfully, err will be null.

Arguments

err: Ospry Error object (see errors)

domImage: HTMLImageElement
The returned image can be directly appended to any HTML container element in the page.

index: Index of the image in the downloaded group of files. If there is only one file being downloaded, this will be 0. Useful for managing UI.

done:
()

Called once all images have completed a download attempt. No imageReady callbacks will be fired after this is called.

Example Usage

ospry.get({
  url: "http://foo.ospry.io/bar/baz.gif",
  format: "png",
  maxHeight: 400,   
  imageReady: function(err, domImage, index) {
    if (err === null) {
      $('body').append(domImage);
    }
  },
});

Errors

Any error you receive from ospry.js will have the following format:

{
  httpStatusCode: // Number
  cause:          // String
  message:        // String
  docsUrl:        // String
}

For example a 404 error will look like this:

{
  httpStatusCode: 404,
  cause: 'not-found',
  message: 'Not found.',
  docsUrl: 'https://ospry.io/docs#error-not-found',
}

You can find a description of each possible error in the other errors section.

Server Libraries

There are some operations you can't perform client-side with your public key. These include managing privacy, claiming, and deleting images.

To help you perform these operations, we've provided the following server-side libraries:

Privacy Controls

Images in Ospry can be either public or private.

Public images can be downloaded by anyone who has the image's URL. These images are automatically cached on a world-wide CDN.

Private images are inaccessible by default. To download a private image, the image's URL must first be signed by your secret key.

Toggling Privacy Permissions

All server libraries have methods to change an image's privacy settings. You must know the image's ID.

All images start out public unless you specify otherwise. When using ospry.up(), you can choose the image's initial privacy setting.

When you make a public image private, we remove the image from the public CDN. This operation should be almost immediate.

Signing URLs

Server-side libraries also have methods for creating cryptographically-signed URLs for private images.

You may specify how long the signed URL grants access to the image. If the URL is accessed after its expiration, Ospry will return a 403 forbidden error.

Claiming

Ospry offers an optional process to verify that client-side uploads are yours. Since your public key is public, anyone could use it to upload images to your account. If claiming is enabled on your account (recommended), unverified images will automatically be deleted after a short time.

All server libraries provide methods to claim client-side uploads as yours. When you receive image metadata back from ospry.up()(2), forward the metadata to your server along with a CSRF token (3). Then use the server library to claim the images (4).

Claiming can be enabled for each pair of API keys. To turn claiming on or off, visit your account page.

Claiming is disabled by default.

Errors

400:
invalid-json

We were unable to parse a JSON request. Check that the JSON is well formed and contains the required fields.

400:
invalid-multipart

We were unable to parse a multipart/form-data request body. Check that your form has the right encoding.

400:
missing-filename

Your request did not include a required filename.

400:
invalid-filename

The filename either contained invalid characters or was not well formed. Try again with a valid filename.

400:
missing-is-private

This probably means that an isPrivate field was provided but didn't have a value.

400:
invalid-is-private

The isPrivate field contained a non-boolean value.

400:
invalid-format

The format query parameter contained an unrecognized format.

400:
invalid-max-height

The maxHeight query parameter must be an integer greater than 0.

400:
invalid-max-width

The maxWidth query parameter must be greater than 0.

400:
invalid-time-expired

The timeExpired query parameter must be parsable in the RFC3339/ISO8601 format (url encoded).

400:
subdomain-not-set

In order to use your production keys you need pick a subdomain in your account settings.

400:
too-many-parts

A multipart form upload contained too many parts.

400:
no-file-parts

A multipart form upload didn't contain any files.

400:
image-too-large

Images must be less than 20 MB.

400:
invalid-image-format

Image was not a valid jpeg, png, or gif.

403:
forbidden

The operation requires a valid API key or a private image was accessed with a public URL or an expired signed URL.

404:
not-found

Image was not found.

405:
method-not-allowed

The HTTP method (e.g. "POST") in the request is not allowed on that resource.

500:
internal-error

Something is wrong on our side. We're working to fix it.

503:
service-unavailable

Some part of our service is overloaded.