NAV
Python JavaScript

Introduction

Welcome to the LeadPages Asset API documentation. It manages images and other media assets including HTML files for LeadPages apps and services. It is designed to be a simple (and somewhat primitive) service that provides a generic platform for asset management, instead of serving specific applications.

This API adheres to the (still-in-development) LeadPages HTTP API Standards document, which is available on GitHub.

We suggest starting with the Walkthrough to begin accessing the API.

For a larger overview, the Architecture section provides some not-so-light reading.

Finally, the API section lists the API endpoints.

Walkthrough

All requests must be authorized by Stargate. You cannot use PyChevron or Charteris to upload a file because it does not support multipart requests. However, you may use it for other operation such as updating or deleting a resource OR for creating a reference asset which just points to an existing URL.

Create

There are two ways to create an asset--multipart or reference. Multipart allows you to upload actual file content whereas reference just points to already existing CDN URL. The former also allows you to upload multiple files in a single request. Please note that we currently do not support asynchronous file uploads.

Multipart Request

First, we will look at how to upload a file using multipart.

You can upload a file by providing at least two parts in the request--one for properties and another for actual file content. You can repeat these parts for uploading multiple files at once. Currently, the maximum filesize is 50MB. For multiple file uploads, the entire request should not exceed more than 50MB.

Single File Upload

An asset can be uploaded by creating an asset resource (POST /asset/v1/assets). The endpoint takes multipart request, first of which defines a JSON object and second of which takes the asset file content.

------WebKitFormBoundaryDhtqWjbqgAw1cz6R
Content-Disposition: form-data; name="json"; filename="blob"
Content-Type: application/json

{"filename": "sample.png", "public": true}
------WebKitFormBoundaryDhtqWjbqgAw1cz6R
Content-Disposition: form-data; name="file-0"; filename="blob"
Content-Type: image/png


------WebKitFormBoundaryDhtqWjbqgAw1cz6R--

Multiple File Upload

You may upload more than one files at a time by alternating the properties-content multipart pairs.

------WebKitFormBoundaryDhtqWjbqgAw1cz6R
Content-Disposition: form-data; name="json"; filename="blob"
Content-Type: application/json

{"filename": "sample.png", "public": true}
------WebKitFormBoundaryDhtqWjbqgAw1cz6R
Content-Disposition: form-data; name="file-0"; filename="blob"
Content-Type: image/png


------WebKitFormBoundaryDhtqWjbqgAw1cz6R
Content-Disposition: form-data; name="json"; filename="blob2"
Content-Type: application/json

{"filename": "sample.png", "public": true}
------WebKitFormBoundaryDhtqWjbqgAw1cz6R
Content-Disposition: form-data; name="file-0"; filename="blob2"
Content-Type: image/png


------WebKitFormBoundaryDhtqWjbqgAw1cz6R--

Boundary

The part boundary is defined by Content-Type header of the request itself (not a section within boundaries), as shown below:

multipart/form-data; boundary=----WebKitFormBoundaryDhtqWjbqgAw1cz6R

Notice there is an extra -- in front of the actual boundaries in the message and at the end of the last boundary as well.

Headers

Each section (within two boundaries) must have Content-Disposition and Content-Type header. Asset API will use the filename and content type information in these headers if JSON object does not specify these values. The name property does not really matter. Asset API will treat the first section as properties and the second section as asset content.

Size Limit

As mentioned above, the entire request must not exceed 50MB. If it does, you will get a 413 status.

Reference Asset

You may create a reference asset which just points to an existing URL that works as the source of truth. Although we discourage the use of this feature, there is a legitimate case--sync between Builder3 and the core app. In order to allow images from the core app to be queried, a reference must be created on the Asset API side.

To create a reference, use application/json content type instead of multipart and utilize fileUri parameter to create the reference. For the sync feature, refer to the Sync section below.

Read

Simply request a GET method on the resource.

    HTTP GET /asset/v1/assets/GrgmQfkzEqp6prBr6Dhj6R

    { "contentType": "image/jpeg", "module": null, "userUuid":
    "RdXx6BNx3x2hLEQ6EGQNrn", "generalType": "image", "size": 1208800, "_meta":
    { "updated": "2015-11-24T21:23:27+00:00", "created":
    "2015-11-24T21:23:19+00:00", "id": "GrgmQfkzEqp6prBr6Dhj6R", "uri":
    "http://asset.docker/asset/v1/assets/GrgmQfkzEqp6prBr6Dhj6R" }, "filename":
    "22598292462_cee2d5a528_k.jpg", "application": null, "fileUri":
    "https://storage.googleapis.com/lp-assets-local/4dj844yjEgmE54YDrBXu8E%2FGrgmQfkzEqp6prBr6Dhj6R",
    "public": true, "metadata": {} }

Update

You may update an existing asset but the following properties are not allowed to be modified:

application, module, fileUri, myImageId

But, you shouldn't be updating your asset. If this is the case, please contact the engineers and notify them of your use case.

Delete

In order to delete, just use DELETE method on the asset resource. For instance, to delete resource GrgmQfkzEqp6prBr6Dhj6R, do the following.

http DELETE /asset/v1/assets/GrgmQfkzEqp6prBr6Dhj6R

If successful, it will be a 204 response.

JSON Parameters

Request

You can specify metadata of the asset you are uploading in the first part of the multipart request. Please note that some properties are permitted for certain operations only. Properties for sync are not listed here.

Key Value
application Optional. The application from which the asset is uploaded. Will be used for filtering in the future.
contentType Optional. The content-type of the file. If this is not specified, Content-Type header in the blob section of the multipart will be used instead.
fileUri Required if creating a reference which is just a soft link to an existing URL. It can be an arbitrary URL that is to be used as the source of truth.
filename Optional. The filename. If this is not specified, Content-Disposition header in the blob section of the multipart will be used instead. Note that this property does not affect file URL in the response. The UUID of the asset will be used instead for constructing the URL.
metadata Optional. An arbitrary JSON dictionary data.
module Optional. More granular source of the asset than application.
size The byte size of the asset content. Only accepted for reference assets.
public Default: true. Always set to true for now. Do not set this to false. It is not supported yet.

Response

Here is the definition of the response you will get:

Key Value
application Optional. The application from which the asset is uploaded. Will be used for filtering in the future.
contentType The content type of the file.
fileUri The public URI of the uploaded file content.
filename The filename.
generalType The general type of the content type. Possible values are: application, audio, image, message, multipart, text, video, x-token
metadata An arbitrary JSON dictionary data.
module Optional. More granular source of the asset than application.
public True if the file content can be accessed publicly. False otherwise.
size The byte size of the asset content.
userUuid The UUID of the owner.

For a single file upload, there will be a single resource whereas for a multiple file upload, there will be multiple resources in the JSON response.

Application and Module

So what are application and module? I will try to explain here.

You can register your application and module before using Asset API so the team can keep track of legit uses of Asset APIs (although you can specify arbitrary values for these properties). Currently, we officially have:

Application Module Description
builder3 image-uploader Builder3's image uploading feature
core image-uploader The core app's image uploading feature

Note that this is how the app (your app) will determine or filter assets that are appropriate for your use. Asset API does not support any filtering at the moment, therefore, you will have to filter them yourself using application and module properties. Remember, other apps can upload assets as well.

Public (vs. Private)

Always set public parameter to false until further notice.

Permission

By default, an asset will be only accessible to the user who created it.

Sync

We only sync between Builder3 and the core app (aka Builder2). This is a somewhat intricate operation, so feel free to reach out to me (david.an@ave81.com) or Joe (joe@ave81.com) for more details.

From Builder3 to Builder2

We sync assets uploaded directly from Builder3 back to Builder2 as well as the assets deleted from Builder3.

Create

Set sync query parameter to true to enable the sync feature.

POST /asset/v1/assets?sync=true

will synchronize the newly created asset to Builder2. The following JSON parameters must be specified with the given values (in addition to required JSON parameters defined above):

Note that only assets with those parameter values will be sync'ed. If the sync fails, the upload request will fail and return 50x.

Delete

Similar to Upload. Just use DELETE method instead. For example,

    DELETE /asset/v1/assets/{asset_id}?sync=true

will attempt to delete the image in the core app first, then the original asset you uploaded.

From Builder2 to Builder3

Refer to the core app documentation for more details on how Builder2 triggers the sync. In summary, Builder2 will create a reference asset that points to the serving URL that AppEngine has generated. Thus, no file content will be sent to Asset API. Make sure to use application/json content type instead of multipart. For deletion, simply DELETE the reference asset. DO NOT specify sync query parameter for creating or deleting reference assets.

If you want to use sync feature, please contact engineers first.

Errors

There are three possible errors when using this API:

Code Description
400 Bad Request. Your request is likely to have malformed data.
401 Unauthorized. You probably did not provide a valid security token or key.
404 Not Found. The resource you are trying to access does not exist, or you do not have access to the resource you are trying to access.
413 Request Entry Too Large. Max filesize has been reached. Try again with a smaller media file.
50x Internal Error. Contact API engineers right away.

API

Request Description
POST /asset/v1/assets Create assets for the authenticated user. You may post more than one asset by alternativing properties-content multiparts. For a single file upload, only one resource is returned. For a multiple file upload, multiple resources are returned in the response.
POST /asset/v1/users/current/assets Same as above.
POST /asset/v1/users/:user_uuid/assets Same as above except use the specified user UUID.
GET /asset/v1/assets Get the list of all assets that belong to the authenticated user.
GET /asset/v1/users/current/assets Same as above.
GET /asset/v1/users/:user_uuid/assets Same as above except use the specified user UUID.
DELETE /asset/v1/assets Bulk delete all assets that belong to the authenticated user.
DELETE /asset/v1/users/current/assets Same as above.
DELETE /asset/v1/users/:user_uuid/assets Same as above except use the specified user UUID.
PATCH /asset/v1/assets/:asset_uuid Updates the asset owned by the authenticated user.
GET /asset/v1/assets/:asset_uuid Get the asset data (not including the asset itself)
DELETE /asset/v1/assets/:asset_uuid Soft deletes the asset. The actual file content of the file URL is not deleted.

Endpoints

/asset/v1

Ping

/asset/v1/ping

Request

GET /asset/v1/ping

Body
Empty

Response

Body
_meta._version String
The current internal version number of the API.
_meta Dictionary
Responses
200 OK
Errors
Empty


Assets

/asset/v1/assets

Request

GET /asset/v1/assets

Get a list of assets. Supports a basic "type" filter for favicons or facebook images.

Body
Empty
Query string
limit Regexp?(\d+)
The maximum number of items to return in the response.
cursor String?
A string representing where a previous request "left off"
search String?

Response

Body
_meta ListingMeta
Meta information about the response.
_items List[Asset]
A list of returned assets.
Responses
200 OK
Errors
400 Bad Request unknown message
400 Bad Request bad content type
400 Bad Request missing Content-Type header
400 Bad Request failed to parse JSON request


Request

POST /asset/v1/assets

Upload an asset. Can be one more multiple multipart POST requests, or a reference request.

TODO: that because this handler uses req's json response and calls the schemas' build_from method directly (which calls materialize), the Response schema set below doesn't actually matter. Refactor this to align with other ASK APIs and just return listings for both single and multiple uploads. The frontends don't consume the response anyway.

Body
contentType String?
filename String?
metadata Dictionary?
public Boolean?
size Integer?
width Integer?
height Integer?
myImageId String?
application String?
module String?
fileUri URI
Query string
sync Enum('true', 'True', 'yes', '1', 'on', 'false', 'False', 'no', '0', 'off')

Response

Body
Empty
Responses
201 Created
Errors
400 Bad Request bad content type
400 Bad Request missing Content-Type header
400 Bad Request failed to parse JSON request
400 Bad Request unknown message
400 Bad Request Malformed Content-Type header
400 Bad Request Bad request
400 Bad Request Invalid multipart content
413 Payload Too Large File is too large
413 Payload Too Large Max filesize exceeded
500 Internal Server Error Upload failed due to sync failure


Request

DELETE /asset/v1/assets

Body
Empty

Response

Body
Empty
Responses
204 No Content
Errors
400 Bad Request unknown message
400 Bad Request bad content type
400 Bad Request missing Content-Type header
400 Bad Request failed to parse JSON request


Favicons

/asset/v1/assets/favicons

Endpoint for listing favicons.

Request

GET /asset/v1/assets/favicons

Query string
limit Regexp?(\d+)
The maximum number of items to return in the response.
cursor String?
A string representing where a previous request "left off"
search String?

Response

Body
_meta ListingMeta
Meta information about the response.
_items List[Asset]
A list of returned assets.
Responses
200 OK
Errors
400 Bad Request unknown message


Facebook

/asset/v1/assets/facebook

Endpoint for listing Facebook-supported images.

Request

GET /asset/v1/assets/facebook

Body
Empty
Query string
limit Regexp?(\d+)
The maximum number of items to return in the response.
cursor String?
A string representing where a previous request "left off"
search String?

Response

Body
_meta ListingMeta
Meta information about the response.
_items List[Asset]
A list of returned assets.
Responses
200 OK
Errors
400 Bad Request unknown message


Asset

/asset/v1/assets/{uuid}

Request

GET /asset/v1/assets/{uuid}

Get an asset resource.

Body
Empty

Response

Body
_meta Meta
Meta information about the resource.
contentType String?
filename String?
metadata Dictionary
public Boolean
size Integer?
width Integer?
height Integer?
myImageId String?
application String?
module String?
fileUri URI
generalType String?
Responses
200 OK
Errors
400 Bad Request bad content type
400 Bad Request missing Content-Type header
400 Bad Request failed to parse JSON request
404 Not Found asset {uuid} not found


Request

PATCH /asset/v1/assets/{uuid}

Update an asset. Disallows updating of certain properties.

Body
contentType String?
filename String?
metadata Dictionary?
public Boolean?
size Integer?
width Integer?
height Integer?
myImageId String?

Response

Body
_meta Meta
Meta information about the resource.
contentType String?
filename String?
metadata Dictionary
public Boolean
size Integer?
width Integer?
height Integer?
myImageId String?
application String?
module String?
fileUri URI
generalType String?
Responses
200 OK
Errors
400 Bad Request bad content type
400 Bad Request missing Content-Type header
400 Bad Request failed to parse JSON request
404 Not Found asset {uuid} not found


Request

DELETE /asset/v1/assets/{uuid}

Body
Empty
Query string
sync Enum('true', 'True', 'yes', '1', 'on', 'false', 'False', 'no', '0', 'off')

Response

Body
Empty
Responses
204 No Content
Errors
400 Bad Request bad content type
400 Bad Request missing Content-Type header
400 Bad Request failed to parse JSON request
404 Not Found asset {uuid} not found
500 Internal Server Error Could not delete.


Fonts

/asset/v1/fonts

Request

GET /asset/v1/fonts

Body
Empty
Query string
limit Regexp?(\d+)
The maximum number of items to return in the response.
cursor String?
A string representing where a previous request "left off"

Response

Body
_meta ListingMeta
Meta information about the response.
_items List[FontFamily]
Responses
200 OK
Errors
Empty


Request

POST /asset/v1/fonts

Body
name String

Response

Body
_meta Meta
Meta information about the resource.
name String
boldFont Font?
boldItalicFont Font?
italicFont Font?
regularFont Font?
cssUri String?
Responses
200 OK
Errors
400 Bad Request Font {name} already exists


Fontfamily

/asset/v1/fonts/family/{uuid}

Request

GET /asset/v1/fonts/family/{uuid}

Body
Empty

Response

Body
_meta Meta
Meta information about the resource.
name String
boldFont Font?
boldItalicFont Font?
italicFont Font?
regularFont Font?
cssUri String?
Responses
200 OK
Errors
400 Bad Request bad content type
400 Bad Request missing Content-Type header
400 Bad Request failed to parse JSON request
404 Not Found {uuid} not found.


Request

POST /asset/v1/fonts/family/{uuid}

Body
Empty

Response

Body
_meta Meta
Meta information about the resource.
name String
boldFont Font?
boldItalicFont Font?
italicFont Font?
regularFont Font?
cssUri String?
Responses
200 OK
Errors
400 Bad Request bad content type
400 Bad Request Bad request.
400 Bad Request missing Content-Type header
400 Bad Request failed to parse JSON request
400 Bad Request Malformed Content-Type header
404 Not Found {uuid} not found.
413 Payload Too Large Max filesize exceeded.
413 Payload Too Large File is too large


Request

PATCH /asset/v1/fonts/family/{uuid}

Body
name String?
boldFont String?
boldItalicFont String?
italicFont String?
regularFont String?

Response

Body
_meta Meta
Meta information about the resource.
name String
boldFont Font?
boldItalicFont Font?
italicFont Font?
regularFont Font?
cssUri String?
Responses
200 OK
Errors
400 Bad Request bad content type
400 Bad Request missing Content-Type header
400 Bad Request failed to parse JSON request
400 Bad Request Font {name} already exists
404 Not Found {uuid} not found.


Request

DELETE /asset/v1/fonts/family/{uuid}

Body
Empty

Response

Body
Empty
Responses
204 No Content
Errors
400 Bad Request bad content type
400 Bad Request missing Content-Type header
400 Bad Request failed to parse JSON request
404 Not Found {uuid} not found.


Font

/asset/v1/fonts/font/{uuid}

Request

GET /asset/v1/fonts/font/{uuid}

Body
Empty

Response

Body
_meta Meta
Meta information about the resource.
name String?
weight Integer(100 < n < 900| n divides 100)
style Enum('regular', 'italic')
size Integer
label String
woffUri String
woff2Uri String
Responses
200 OK
Errors
404 Not Found {uuid} not found.


Definitions

ListingMeta

ListingMeta
limit Integer
The requested limit on the number of items.
total Integer?
The number of items in the database.
count Integer
The total number of items in the response.
cursor String?
This is used in conjunction with limit to paginate through lists of items.

Asset

Asset
_meta Meta
Meta information about the resource.
contentType String?
filename String?
metadata Dictionary
public Boolean
size Integer?
width Integer?
height Integer?
myImageId String?
application String?
module String?
fileUri URI
generalType String?

Meta

Meta
id String
The resource's unique identifier.
uri URI
The resource's absolute URI.
created DateTime
When the resource was created.
updated DateTime
When the resource was last updated.
deleted DateTime?
When the resource was deleted.

Font?

Font?
_meta Meta
Meta information about the resource.
name String?
weight Integer(100 < n < 900| n divides 100)
style Enum('regular', 'italic')
size Integer
label String
woffUri String
woff2Uri String

FontFamily

FontFamily
_meta Meta
Meta information about the resource.
name String
boldFont Font?
boldItalicFont Font?
italicFont Font?
regularFont Font?
cssUri String?