Documentation
FrançaisEnglish
Contact Us
 

Getting started with the Pictures API

Sometimes, you may only need a service to identify one image from another, good news there are entry points for that. And because Images have a meaning only in your context, you can associate metadata and keywords to your images. To access to this service, You only need a login, an OrganizationId (you get it when you log in), and an API Key for searching.

This part is optimized for High Volumes / High Speed image recognition. No image is stored in the platform, and data is indexed in a fast database. Here we will guide you from the authentication on the platform until the search of an image. This API also allows to search an image based on the color of another image. The principle stays the same but if you need more information please do not hesitate to contact us.

If you need to enrich an image with complex actions, languages and styles, you can consult the documentation of the EnrichedImages API


Request AccessTo get access to our services, you will need an account. To request an account to our development team, please fill in that request form.

Contact UsShould you have any feedback or question please feel free to contact us.

-> To go deeper, the full API reference documentation is available here.

-> JQuery code samples come from the Javascript SDK (GitHub).

Match

What would you like to do today?

Login using OAuth2

To have access to our service you must be logged. It means you need an account. With your API Key - that you get on the platform in the admin tab - and with your login, you get an token. This token must be send with all the add/get requests and is valid for 15 days.

Authentication

Get a Token

- Syntax:

Build a POST request of type application/x-www-form-urlencoded.

POST https://api.onprint.com/token
- Parameters:
headers: Apikey : the APi Key of your application ApiKey:[your Api Key] data: grant_type: username : your login account password : your password The content is form-data, built like this: grant_type=password&username=toto@ltu.com&password=test
- Returns:

A Json containing the account data and the access token

- cUrl:
curl -X POST -H "contentType: application/x-www-form-urlencoded" "https://api.onprint.com/token" -d "grant_type=password&username=toto@ltu.com&password=test" -H "ApiKey:[your API key]"

- JQuery:
function login(username, password, apikey, callback) {

    if (username == '' || password == '') {
        alert('missing username or password');
        return;
    }
    var url = 'https://api.onprint.com/token';
    var formData = 'grant_type=password&username=' + encodeURIComponent(username) + '&password=' + encodeURIComponent(password);
    $.ajax({
        url: url,
        type: 'POST',
        accept: 'application/json',
        headers: {
            'ApiKey': apikey
        },
        contentType: 'application/x-www-form-urlencoded',
        data: formData,
        success: function (data, status) {
            $.ajaxSetup({ beforeSend: function (xhr) {
                xhr.setRequestHeader('Authorization', 'bearer ' + data.access_token);
            } });
            callback(data, status);
        },
        error: function (xhr, status) {
            callback(xhr, status);
        }
    });
}
- Example of response:

The response contains the token in the field access_token. It has an expiration date. It also contains your userId as well as your organizationId

{"access_token":"AQAAANCMnd8BFdERjHoAwE_Cl-sBAAAAET6D6vU6i0Kl63(...)","token_type":"bearer","expires_in":1209599,"userName":"toto@toto.com","userId":"085201a8-98a2-0f5c-3311-aa415563ed05","organizationId":"1a855da8-4510-0f5c-3311-aa415563da95","organizationName":"totorg","roles":"System.Data.Entity.DynamicProxies.UserRole_CDCE067A6D23","apiversion":"2.0.6",".issued":"Thu, 09 Feb 2017 15:51:04 GMT",".expires":"Thu, 23 Feb 2017 15:51:04 GMT"}


Set the authentication header for API calls

Use the OAuth2 authentication for API calls that requires it. Set a header in your get/add requests like this:

 Authorization: Bearer AQAAANCMnd8BFdERjHoAwE_Cl-sBAAAAET6D6vU6i0Kl63(...)


Add a picture

Add a picture

Where am I?

When you log in, you get access to your organization (often it's your enterprise name) and all its children, which can be other organizations (your clients or your different applications such as test, prod, preprod...). These are called nodes. To navigate through the node arborescence, you can use the nodes endpoint.

- Syntax:

As you may have noticed in part 1, when you log in, you are returned your own userId as well as your organizationId. If you want to see what nodes are children of your organization, try:

GET https://api.onprint.com/api/nodes/[nodeId]/organizations

And if you want to go deeper in the arborescence, call the same thing with any other node Id.

GET https://api.onprint.com/api/nodes/[nodeId]/nodes

Tree

- Parameters:
headers: Authorization: the access token "Authorization: bearer ${TOKEN}"
- Returns:

A JSON object with the nodes children's data.

- Curl:
curl -H "Authorization: bearer ${TOKEN}" 'https://api.onprint.com/api/nodes/[nodeId]/nodes'
- JQuery:

For typename in organizations:

function getChildren(nodeId, typename, callback) {
    $.ajax({
        method: "GET",
        url: getUrl("/api/nodes/" + nodeId + "/" + typename),
        success: function (data, status, xhr) {
            callback(data, status, xhr);
        },
        error: function (xhr, status) {
            callback(null, status, xhr);
        }
    });
}

Organize your pictures

When you want to create a new organization, you can POST it (Content-Type:application/json). Organizations could help you to organise your pictures by applications (test, preprod, prod...).

- Syntax:
POST https://api.onprint.com/api/[organizations]
- cUrl:
curl -X POST --header 'Content-Type: application/json' --header 'Accept: text/plain' --header "Authorization: Bearer ${TOKEN}" -d '{"Name": "test","LanguageCode": "fr-FR","ParentId":"[Id]"}' 'https://api.onprint.com/api/Organizations'
- Parameters:
headers: Authorization: the access token data: Name LanguageCode ParentId
- Query:

For typename in nodes, organizations:

function postOne(object, typename, callback) {
    $.ajax({
        method: "POST",
        url: "https://api.onprint.com/api/" + typename,
        data: JSON.stringify(object),
        contentType: "application/json",
        dataType: "json",
        success: function (data, status, xhr) {
            callback(data, status, xhr);
        },
        error: function (xhr, status) {
            callback(null, status, xhr);
        }
    });
}

The node details are given as a JSON object in the body.

Create a new Picture

Request

A Picture is a simple, single Image.

Property Mandatory? Type Description Comment
Id String Picture Id in the platform. Read-Only, generated
_objectId String Internal Id, useful for pagination (see ) Read-Only, generated
Name * String Picture name. Can be your own identifier
Data String Picture metadata. You can put whatever you want, in any format.
OrganizationId * String Organization"s Id. Pictures will be listed under it.
BigThumbnailUrl String URL of the Picture"s Thumbnail. (only for display) Read-Only, generated
SessionId String Session identifier that you can use to link events to the IR. Read-Only, generated
RecognitionScore String Score of the image recognition, regarding the query image. Read-Only, generated
Keywords String[] Keywords attached to the picture, to filter searches.

The POST method is used to add a picture by sending the image file and its properties.

- Syntax:
POST https://api.onprint.com/api/pictures
- Parameters:

The request body content type must be Multipart (multipart/form-data). The content is made of a File data (named file) and a Form data (named picture). If you don't know how to make a Multipart request, see the RFC 1341 part 7.2, or Java, NodeJS, .NET tools.

  • headers:
    • Authorization : the access token_type
  • form-data:
    • picture : JSON object with image's details:
      • Name
      • ContentType :Image/jpeg
      • OrganizationId
  • file : image or PDF
- Returns:

The response is a JSON object representing the new picture. HTTP status is 201 - Created.

-cUrl:
curl -s -i -F 'picture={"Name":"veggies","ContentType":"image/jpeg","OrganizationId":"[id]"};type=application/json' -F 'file=@/Users/Downloads/veggies.jpeg;type=image/jpeg;filename=veggies.jpg' -X POST -H 'Content-type: multipart/form-data' -H 'Accept: application/json' -H "Authorization: bearer ${TOKEN}" 'https://api.onprint.com/api/Pictures/'
- JQuery:

File parameter of function postPicture must be a binary file. We partially reuse what was done for a Node before:

function getBoundary() {
    return "XXX" + (new Date).getTime() + "XXX";
}

function createFileContent(filename, attachmentname, filetype, boundary) {
    var contentFile = "--" + boundary + "\r\n";
    contentFile += "Content-Disposition: attachment; name=" + attachmentname + "; filename="" + filename + ""\r\n";
    contentFile += "Content-Type: " + filetype + "\r\n";
    contentFile += "\r\n";
    return contentFile;
}

function createFormContent(object, objectname, boundary) {
    var contentForm = "--" + boundary + "\r\n";
    contentForm += "Content-Type: application/json; charset=utf-8\r\n";
    contentForm += "Content-Disposition: form-data; name=" + objectname + "\r\n";
    contentForm += "\r\n";
    contentForm += JSON.stringify(object) + "\r\n";
    return contentForm;
}

function postPicture(file, picture, callback) {
    var boundary = getBoundary();

    var contentForm = createFormContent(picture, "picture", boundary);
    var contentFile = createFileContent(file.name, "file", file.type, boundary);

    var blob = new Blob([contentForm, contentFile, file, createEndContent(boundary)]);

    $.ajax({
        method: "POST",
        url: "https://api.onprint.com/api/pictures),
        data: blob,
        contentType: "multipart/form-data; boundary="" + boundary + """,
        dataType: "json",
        processData: false,
        success: function (data, status, xhr) {
            callback(data, status, xhr)
        },
        error: function (xhr, status) {
            callback(null, status, xhr)
        }
    });
}
- Example of response:

Internal identifiers are filled:

{
    "_objectId": "507f1f77bcf86cd799439011",
    "Id": "31140da6-b422-44fd-82c1-847820f954e7",
    "OrganizationId": "37e2cc76-8fcb-4864-9557-866d4bd47316",
    "Name": "Veggies",
    "Data": "1234568799|Test|784845122|###",
    "BigThumbnailUrl": "https://static.ltu-engine.com/thumb-200x200/image/0ILHbFNqj3QwB8yH/8dd90fa85898fb14cc904dfd52925f3e"
  }

FileData (file)

The picture itself. It can be a JPEG, PNG, GIF image. The MIME type has to be given in the file content type. There is no special requirement regarding file size or quality. However, you must keep in mind that to be recognized, the image must contain enough details or points. And if you send us very high quality images, it will be slow and worth nothing because the platform resizes the images for recognition.

FormData (picture)

Contains a Picture object. The mandatory fields are:

  • OrganizationId, the Id of the organization you want to create it in
  • Name, the picture name.

Example:

{
    "OrganizationId": "5215adae-e451-44c8-a930-9e4afe88bba9",
    "Name": "Veggies",
    "Data": "1234568799|Test|784845122|###" //anything you need, String or Json or Binary or whatever you like...
}

Tree

Search for a Picture

Scan

By sending an image

Request

- Syntax:

For an image search, it will be a multipart (multipart/formdata) POST:

POST https://api.onprint.com/api/Pictures/Search
- Parameters:

LTU will require some information from the device to store useful clickstream information, and to authenticate using the API key. This call does not need a oAuth authentication. This is why you will have to set several headers to the call. Here is the full list. You can also find it in the reference documentation.

Header Type Example Mandatory?
SessionId Unique Identifier 2252dda8-ce26-49d8-98e0-3fbe76181435
ApplicationInstanceId Unique Identifier CCE20149-0F83-43FE-A167-C4E1A3335FC9
ApplicationName String My Super App *
ApplicationVersion String 1.7.4.121 *
ApiKey Unique Identifier 3ad17b48a8a4f08f8949a *
DeviceName String iPhone de Thomas *
DeviceSystemVersion String 10.2.1 *
DeviceSystemVersionName String iPhone OS
SdkName String My Super App SDK
SdkVersion String 1.7.4 *
DeviceConnectivity String WiFi
DeviceScreenDiagonal String 0
DeviceScreenHeight String 568
DeviceScreenWidth String 320
Longitude Floating point 44.946709
Latitude Floating point -93.175379
Language String fr-FR

The mandatory headers are Application Name and version, Sdk version (if you are developing a single application, Sdk version = Application version), Device name and system version, and APIkey.

Once you are able to get all this information from the device, you are ready to do the request.

  • headers:
    • API_KEY
    • ApplicationName
    • ApplicationVersion
    • DeviceName
    • DeviceSystemVersion
    • SdkVersion
    • ...
  • form-data:
    • query:
      • keywords
  • file : image or pdf
- Returns:

If the image is found, you will get a 200 OK and a list of matching Picture objects: images and their metadata, with a recognition score, the highest being 1.

- cUrl:
curl -s -i -F  'query={"Keywords":["legumes"]};type=application/json' -F 'file=@/Users/Documents/onprint/veggies.jpg;type=image/jpeg;filename=veggies.jpg'  -X POST  -H 'Content-type: multipart/form-data' -H 'Accept: application/json' -H 'ApiKey: [ApiKey]' -H 'ApplicationInstanceId: ApiTester' -H 'ApplicationName: ApiTester' -H 'ApplicationVersion: 0.0' -H ‘DeviceName: Po -H 'DeviceSystemVersion: 0.0' -H 'DeviceSystemVersionName: Script' -H 'SdkName: Script' -H 'SdkVersion: 1.0' 'https://api.onprint.com/api/Pictures/Search'
- JQuery:
function getBoundary() {
    return "XXX" + (new Date).getTime() + "XXX";
}

function createFileContent(filename, attachmentname, filetype, boundary) {
    var contentFile = "--" + boundary + "\r\n";
    contentFile += "Content-Disposition: attachment; name=" + attachmentname + "; filename="" + filename + ""\r\n";
    contentFile += "Content-Type: " + filetype + "\r\n";
    contentFile += "\r\n";
    return contentFile;
}

function createFormContent(object, objectname, boundary) {
    var contentForm = "--" + boundary + "\r\n";
    contentForm += "Content-Type: application/json; charset=utf-8\r\n";
    contentForm += "Content-Disposition: form-data; name=" + objectname + "\r\n";
    contentForm += "\r\n";
    contentForm += JSON.stringify(object) + "\r\n";
    return contentForm;
}

function searchPicture(file, searchQuery, callback) {
    var query = {
        Keywords:["painting"]
    };
    var boundary = getBoundary();

    var contentForm = createFormContent(query, "query", boundary);
    var contentFile = createFileContent(file.name, "file", file.type, boundary);


    var blob = new Blob([contentForm, contentFile, file, createEndContent(boundary)]);
    $.ajax({
        method: "POST",
        url: "http://api.onprint.com/api/Pictures/Search",
        data: blob,
        contentType: "multipart/form-data; boundary="" + boundary + """,
        dataType: "json",
        processData: false,
        headers: {
            "ApplicationInstanceId": searchQuery.ApplicationInstanceId,
            "ApplicationName": searchQuery.ApplicationName,
            "ApplicationVersion": searchQuery.ApplicationVersion,
            "ApiKey": searchQuery.ApiKey,
            "DeviceName": searchQuery.DeviceName,
            "DeviceSystemVersion": searchQuery.DeviceSystemVersion,
            "DeviceSystemVersionName": searchQuery.DeviceSystemVersionName,
            "SdkName": searchQuery.SdkName,
            "SdkVersion": searchQuery.SdkVersion,
            "Latitude": searchQuery.Latitude,
            "Longitude": searchQuery.Longitude
        },
        success: function (data, status, xhr) {
            if (xhr.status == 200) {
            }
            if (xhr.status == 204) {
            }
            callback(data, status, xhr);
        },
        error: function (xhr, status) {
            callback(null, status, xhr);
        }
    });
}
- Example of Response:

Here is an example of what you should get:

[
    {
        "_objectId": "507f1f77bcf86cd799439011",
        "Id": "31140da6-b422-44fd-82c1-847820f954e7",
        "OrganizationId": "37e2cc76-8fcb-4864-9557-866d4bd47316",
        "Name": "La Joconde",
        "Data": "123548481512000",
        "BigThumbnailUrl": "https://static.ltu-engine.com/thumb-200x200/image/0ILHbFNqj3QwB8yH/8dd90fa85898fb14cc904dfd52925f3e",
        "SessionId": "ff4d6e93-bddf-4584-bfb6-de5259ae6c2c",
        "RecognitionScore": 0.99822000,
        "Keywords":["painting"]
    },
    {
        "_objectId": "90876f77bca86cd799439871
        "Id": "ab889076-b422-44fd-82c1-847820f954e7",
        "OrganizationId": "37e2cc76-8fcb-4864-9557-866d4bd47316",
        "Name": "Joconde Bottero",
        "Data": "{\"internalid\":\"2\", \"info\":\"personal info\"}",
        "BigThumbnailUrl": "https://static.ltu-engine.com/thumb-200x200/image/0ILHbFNqqzf87KHi/5a6fc5812f9e68122082951b68c18060",
        "SessionId": "ff4d6e93-bddf-4584-bfb6-de5259ae6c2c",
        "RecognitionScore": 0.75643000,
        "Keywords":["painting"]
    }
]

FileData (file)

The query JPEG image itself. No need to make it big: our recommandation is to pre-treat it before sending to the server:

  • put it in black and white, the image recognition only needs to see contrasts,
  • resize so that the shortest side is 350px
  • reduce JPEG quality to 0.75

The MIME type must be image/jpeg.

FormData (query)

Contains the Json query object that goes with the content. If you have no special query and only want to do a simple match, leave it empty and send a blank JSON. If you work with keywords and want to filter the results with this keyword, add keywords as a string array in the query object:

{
    "Keywords":["cat", "animal"]
}

There is also a compatibility between EnrichedImages and Pictures. You can use the EnrichedImages API to scan a Picture (the opposite is not true). The result will be a single (best recognition score) Enriched Image, with no language, no styles, only a "Data" field containing the picture data.

By id

To get the same result by providing the image Id only (no image search), you can call a GET:

- Syntax:
GET https://api.onprint.com/api/Pictures/[Id]" The only difference is that the RecognitionScore will be null or 0.
- Parameters:
headers: Authorization: the access token
cUrl:
curl -H "Authorization: bearer ${TOKEN}" 'https://api.onprint.com/api/Pictures/[id]'

The LTU platform stores every flash, so that you can get clickstream information.

That's it! You went through all our quickstart. We hope you liked it. We would love to hear from your feedback, so for anything please contact us! You can now start ahead, and if you need more, don't forget the reference documentation.

We also have a Swagger page, useful to test a little but not fully configured (missing headers for EnrichedImages and Clicks, so it won't work, multipart stuff a little handmade...). You can find it here: https://api.onprint.com/Swagger

Thank you

Thank you for your interest in the LTU API. Any question let us know.