NAV Navbar
cURL Python

Introduction

Welcome to the IMATAG API!

This API is intended for enterprise customers to register on-premises watermarked media and track their usage on the Internet or via PDF analysis.

Authentication

We use token authorization via HTTP header, to provide secure access to your account via our API.

To authorize, use this code:

import requests

# with requests library, you can just pass the correct header with each request
headers = {"Authorization":"Token putyourapitokenhere"}
response = requests.get("api_endpoint_here", headers=headers)
# With shell, you can just pass the correct header with each request
curl "api_endpoint_here" \
  -H "Authorization: Token putyourapitokenhere"

Make sure to replace putyourapitokenhere with your API key.

IMATAG uses API keys to allow access to the API. Your API key is available in your account settings on IMATAG or via the API endpoint

IMATAG API expects the API key to be included in all API requests to the server in a header that looks like the following:

Authorization: Token putyourapitokenhere

Request IDs

Each API request has an associated request identifier. You can find this value in the response headers, under X-Request-Id. If you need to contact us about a specific request, providing the request identifier will ensure the fastest possible resolution.

Versioning

The versioning of the API is specified as part of the URI. For instance, in order to use v1 of the API the request URI should begin with /v1 followed by a specific endpoint.

https://imatag.com/api/v1

Pagination

All endpoints which return collections of objects use pagination. All those endpoints return the following attributes in their response:

Attribute Description
count Total number of objects
next url of the next objects in the sequence (null if end is reached)
previous url of the previous objects in the sequence (null at the start)
<attr_name> list of paginated objects (current chunk)

To navigate the collection, you need to iteratively do GET requests at the url provided in the next attribute for each chunk of the collection.

Rate Limits

# Example response headers

HTTP/1.0 200 OK
Date: Tue, 04 Dec 2018 09:31:20 GMT
Server: WSGIServer/0.1 Python/2.7.9
X-RateLimit-Secondly: 10
X-RateLimit-Secondly-Remaining: 9
X-RateLimit-Daily: 50000
X-RateLimit-Daily-Remaining: 49996
...
# Example response headers

HTTP/1.0 200 OK
Date: Tue, 04 Dec 2018 09:31:20 GMT
Server: WSGIServer/0.1 Python/2.7.9
X-RateLimit-Secondly: 10
X-RateLimit-Secondly-Remaining: 9
X-RateLimit-Daily: 50000
X-RateLimit-Daily-Remaining: 49996
...
# Example error response headers

HTTP/1.0 429 Unknown Status Code
Date: Tue, 04 Dec 2018 09:44:48 GMT
X-RateLimit-Secondly: 10
X-RateLimit-Secondly-Remaining: 0
X-RateLimit-Daily: 50000
X-RateLimit-Daily-Remaining: 49932
Retry-After: 1
...
# Example error response headers

HTTP/1.0 429 Unknown Status Code
Date: Tue, 04 Dec 2018 09:44:48 GMT
X-RateLimit-Secondly: 10
X-RateLimit-Secondly-Remaining: 0
X-RateLimit-Daily: 50000
X-RateLimit-Daily-Remaining: 49932
Retry-After: 1
...

IMATAG has the following global limits in place for API requests:

Customers exceeding either of those limits will receive error responses with a 429 response code.

Each API request will include the following rate limit headers in the response.

When running into a limit, you'll get an error response with an additional header Retry-After to indicate how many seconds you must wait before making another call.

If you're running into the Secondly/Minutely/Hourly limit, you should throttle the requests that your app is making to stay under that limit. If you find you're still hitting the call limits, or the daily limit is too small for your needs, please contact us with as many details as possible about what APIs you're using, how you're using them, and which limit you're hitting.

API Playground

If you want to try out our API in a secure playground, without using your own account, you can use our api.demo account, which has limited 10Mb quota on the uploads folder. Only the uploads folder is writable, the other ones are only readable.

To use this account, you'll need to use the authorization token fd8fef6e430595edc3bab691d9a83230f0a56b99.

This account contains CC0-watermarked images that were uploaded and tracked on the Internet via our crawlers for demo purpose (to find similar or watermarked copies). You'll be able to see thoses images & track their detected usage via the API.

eiffel tower paris sunset paris

Image formats

To use images directly on endpoints that support simple upload, use the corresponding media type (content-type header) for each image format:

Image Format Media Type
JPEG image/jpeg

Status Codes / Errors

Errors returned by the API may have a response body in the following form:

{
    'status_code': <http status code>,
    'code': 'optional_error_code',
    'details': 'either human readable message about the error or a nested structure with more details',
    'errors': 'a list or errors details when multiple errors occurred'
}
{
    'status_code': <http status code>,
    'code': 'optional_error_code',
    'details': 'either human readable message about the error or a nested structure with more details',
    'errors': 'a list or errors details when multiple errors occurred'
}

IMATAG uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, etc.). Codes in the 5xx range indicate an error with IMATAG's servers.

Status Code Meaning
200 OK -- Everything worked as expected.
201 Created -- A new resource was created.
204 No Content -- The resource was properly deleted - or no content was available to be returned
--- ---
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong. See Authentication.
403 Forbidden -- You don't have enough permission to access the requested resource.
404 Not Found -- The resource could not be found.
405 Method Not Allowed -- You tried to access a resource with an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
409 Conflict -- The request could not be completed due to a conflict with the current state of the target resource.
410 Gone -- The requested endpoint has been removed from our servers.
411 Length Required -- The body is empty or the Content-Length is missing in the request headers.
415 Unsupported Media Type -- The content of the request is not in a format supported by the endpoint.
429 Too Many Requests -- You're requesting too many resources! See Rate Limits.
--- ---
500 Internal Server Error -- We had a problem with our server. Try again later.
501 Not Implemented -- The requested endpoint is documented by not yet developped. It will be available in the future.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.
504 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

API Endpoints

Below is the list of all available endpoints & their full description: this is API time!

Media

The media endpoint allows you to register and manage your media on IMATAG. The management part is quite standard: you PUT your media somewhere, and you can afterward GET it or DELETE it. What sets us apart is that all media you have added IMATAG is registered which means two things:

The flipside is that any media which has been marked but not registered on IMATAG or which has been deleted won't be searched for anywhere and we won't be able to find it's watermark even from a manual query.

Media are organised in a folder tree structure. There are few constraints on the folder structure/naming:

Media object

This model defines the list of attributes for all objects accessible along the path i.e. folder, image, document, etc.

Argument Description
url The URL of the media
path The path of the media
created The date of creation of the media
type The type of object: folder, image, document
children For folder, the list of objects contained in that folder (paginated)
image For image, the static URL of the watermarked thumbnail preview.
exclusive For image, indicates wether an image is exclusive or not. If not specified, exclusivity is unknown.
web_matches For image, the URL of the list of web matches (see Web Match object) filtered on this image
press_matches For image, the URL of the list of press matches (see Press Match object) filtered on this image

List a folder

import requests

headers = {
    'Authorization': 'Token fd8fef6e430595edc3bab691d9a83230f0a56b99',
}
response = requests.get('https://imatag.com/api/v1/media/api.demo/images', headers=headers)
curl https://imatag.com/api/v1/media/api.demo/images \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "children": [
        {
            "created": "2018-07-20T15:16:07.777535Z",
            "path": "api.demo/images/new-york",
            "type": "folder",
            "url": "https://imatag.com/api/v1/media/api.demo/images/new-york"
        },
        {
            "created": "2018-07-20T15:13:06.259863Z",
            "path": "api.demo/images/paris",
            "type": "folder",
            "url": "https://imatag.com/api/v1/media/api.demo/images/paris"
        }
    ],
    "created": "2018-07-20T15:04:33.221902Z",
    "next": null,
    "path": "api.demo/images",
    "previous": null,
    "type": "folder",
    "url": "https://imatag.com/api/v1/media/api.demo/images"
}

This endpoint lists the content of a folder at the given path. Note that the children list is paginated so you might have to iterate to get all children. The children attribute is only returned for the current folder and not for any subfolders. If you need the full hierarchy, you will need to recursively GET the url attribute of each subfolder.

HTTP Request

GEThttps://imatag.com/api/v1/media/<homedir>/<path>

URL Parameters

Parameter Required Description
homedir false The user home directory where to list media from (e.g. jdoe).
path false The path of the subfolder(s) to list media from (e.g. images/2018) within a home directory.

Response description

See Media object

Get a media

import requests

headers = {
    'Authorization': 'Token fd8fef6e430595edc3bab691d9a83230f0a56b99',
}
response = requests.get('https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg',
                        headers=headers)
curl https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "created": "2018-07-20T15:15:49.548216Z",
    "image": "https://static1.imatag.com/54578,15ec5ca69f80719a",
    "path": "api.demo/images/paris/tour-eiffel.jpeg",
    "press_matches": "https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg/matches/press/",
    "type": "image",
    "url": "https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg",
    "user_matches": "https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg/matches/user/",
    "web_matches": "https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg/matches/web/"
}

This endpoint retrieves information about the media at a given path.

HTTP Request

GEThttps://imatag.com/api/v1/media/<homedir>/<path>/<filename>

URL Parameters

Parameter Required Description
homedir true The user home directory where to list media from (e.g. jdoe).
path false The folder(s) path where to store the media within your home directory (e.g. images/2018)
filename true The file name of the file that will be used on our servers (e.g. new-york.jpg)

Response description

See Media object

Register a new media

You can download this watermark file to run the example.

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
    "Content-Type": "application/lmk",
}
lmk = open("./registration.lmk", "rb").read()
response = requests.put("https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg",
                        data=lmk, headers=headers)

curl -X PUT \
  https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg \
  -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
  -H "Content-Type: application/lmk" \
  --data-binary @- < ./registration.lmk

The above command returns JSON structured like this:

{
    "created": "2019-01-02T15:09:17.145580Z",
    "image": "https://static4.imatag.com/208368,28c25e65d3e1baad",
    "path": "api.demo/uploads/2018/my-image.jpg",
    "press_matches": "https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg/matches/press/",
    "type": "image",
    "url": "https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg",
    "user_matches": "https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg/matches/user/",
    "web_matches": "https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg/matches/web/"
}

This endpoint registers a previously watermarked media using the registration (LMK) file generated by the watermarking software or the API's watermarking endpoint.

HTTP Request

PUThttps://imatag.com/api/v1/media/<homedir>/<path>/<filename>

URL Parameters

Parameter Required Description
homedir true The home directory where to upload the media. This is generally your own username or another client folder for which you're granted permission (e.g. jdoe)
path false The optional subfolder path, within your home directory, where to store the media (e.g. images/2018)
filename true The file name & extension of the image to register. It will be its name on our servers & in your account.

Request content

The content of the request must be either:

Response content

If the request is successful, the response is the newly created Media object

Register non-watermarked image for similar-image tracking only

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
    "Content-Type": "image/jpeg",
}
image = open("./tour-eiffel.jpeg", "rb").read()
response = requests.put("https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg",
                        data=image, headers=headers)
curl -X PUT \
  https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg \
  -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
  -H "Content-Type: image/jpeg" \
  --data-binary @- < ./tour-eiffel.jpeg

The above command returns JSON structured like this:

{
    "created": "2019-01-02T15:09:21.504858Z",
    "image": "https://static2.imatag.com/175281,28c25f21e758a67d",
    "path": "api.demo/uploads/2018/my-image.jpg",
    "press_matches": "https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg/matches/press/",
    "type": "image",
    "url": "https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg",
    "user_matches": "https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg/matches/user/",
    "web_matches": "https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg/matches/web/"
}

This endpoint allows to register non-watermarked images as a new media. The request is similar to the default media creation, except the content shall be an image directly.

This allows limited features with uploaded images, compared to watermarked media. Images can only be searched for other images with similar visual content:

For example, similar visual content images can produce matches for the same-looking but different photos, as shown below:

eiffel tower A eiffel tower B

Request content

The content of the request must be either:

Response content

If the request is succesful, the response is the newly created Media object

Register an exclusive image

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
    "Content-Type": "image/jpeg",
    "X-Lamark-Exclusive": True,
}
image = open("./tour-eiffel.jpeg", "rb").read()
response = requests.put("https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg",
                        data=image, headers=headers)
curl -X PUT \
  https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg \
  -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
  -H "Content-Type: image/jpeg" \
  -H "X-Lamark-Exclusive: True" \
  --data-binary @- < ./tour-eiffel.jpeg

The above command returns JSON structured like this:

{   
    "type": "image",
    "exclusive": true,
    ...
}

When registering an image, you can flag it as exclusive,

Delete an existing media

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.delete("https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg",
                           headers=headers)
curl -X DELETE \
  https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

This endpoint deletes and unregisters an existing media.

HTTP Request

DELETEhttps://imatag.com/api/v1/media/<homedir>/<path>/<filename>

URL Parameters

Parameter Required Description
homedir true The home directory where to upload the media. This is generally your own username or another client folder for which you're granted permission (e.g. jdoe)
path false The optional subfolder(s) where the media is stored (e.g. images/2018)
filename true The file name and extention of the media to delete

Delete an existing folder

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.delete("https://imatag.com/api/v1/media/api.demo/uploads/2018",
                           headers=headers)
curl -X DELETE \
  https://imatag.com/api/v1/media/api.demo/uploads/2018 \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

This endpoint deletes a folder and all of its content (subfolders, images, documents, etc.) recursively. All media contained within will be unregistered.

HTTP Request

DELETEhttps://imatag.com/api/v1/media/<homedir>/<path>

URL Parameters

Parameter Required Description
homedir true The user home directory that contains the subfolder to delete (e.g. jdoe).
path true The path of the subfolder to delete (e.g. images/2017).

Matches

Matches carry information on a matched image for a given query. The matched image is described by the Image object, which may refer to either an image registered on IMATAG or an image from the Web. Match information depend also on the source of the query, which may be images from the Web, documents from Press releases, or images and documents submitted via the Search API.

Image Object

Attribute Description
url URL where to find the image content
type type of image, either registered for images registered via the Media API, or web for images found on the Web
width width of the image in pixels
height height of the image in pixels

Additionally, images of type web have these extra fields:

Attribute Description
crawl_date date at which the image was found the first time by our crawlers
page_url URL of the page containing the image
md5 MD5 hash of the image content (optional)
last_modified_date date at which the image file was put on the server from which it was downloaded, if available (optional)

Web Matches

This endpoint lists all web matches found (similar and watermarked) on the Internet by our crawlers.

HTTP Request

GEThttps://imatag.com/api/v1/matches/web

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.get("https://imatag.com/api/v1/matches/web", headers=headers)
curl https://imatag.com/api/v1/matches/web/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "count": 178,
    "next": "https://imatag.com/api/v1/matches/web/?cursor=cD0xNTMyODAyMjk0MzAzJmM9MTc4",
    "previous": null,
    "results": [
        {
            "created": "2018-08-10T14:21:50.568016Z",
            "paths": [
                {
                    "created": "2018-07-20T15:15:43.305448Z",
                    "image": "https://static3.imatag.com/54581,15ec5c5961692db6",
                    "path": "api.demo/images/paris/moulin-rouge.jpeg",
                    "type": "image",
                    "url": "https://imatag.com/api/v1/media/api.demo/images/paris/moulin-rouge.jpeg"
                }
            ],
            "query_page_url": "http://lisaballtraveldesign.com/category/slides/page/2/",
            "query_url": "http://lisaballtraveldesign.com/wp-content/uploads/Paris2Free-600x350.jpeg",
            "type": "web",
            "url": "https://imatag.com/api/v1/matches/94991655/",
            "watermarked": false
        },
        {
            "created": "2018-08-10T13:31:33.662711Z",
            "paths": [
                {
                    "created": "2018-07-20T15:15:47.158967Z",
                    "image": "https://static2.imatag.com/54582,15ec5c8cca8206f8",
                    "path": "api.demo/images/paris/louvre.jpeg",
                    "type": "image",
                    "url": "https://imatag.com/api/v1/media/api.demo/images/paris/louvre.jpeg"
                }
            ],
            "query_page_url": "http://www.ojornaldeuberlandia.com.br/2017/12/05/governo-brasileiro-leva-startups-franca-em-busca-de-investidores/",
            "query_url": "http://www.ojornaldeuberlandia.com.br/wp-content/uploads/2017/12/WhatsApp-Image-2017-12-05-at-10.08.19.jpeg",
            "type": "web",
            "url": "https://imatag.com/api/v1/matches/94988160/",
            "watermarked": false
        },
        "..."
    ]
}

Filtering (non-)watermarked matches & by date

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.get("https://imatag.com/api/v1/matches/web", params={
    'watermarked': True, 'date': '2018-08-02'},
                        headers=headers)

response = requests.get("https://imatag.com/api/v1/matches/web", params={
    'watermarked': True, 'date_gt': '2018-08-01', 'date_lte': '2018-08-02T12:45:00Z'},
    headers=headers)
curl 'https://imatag.com/api/v1/matches/web/?watermarked=true&date=2018-08-02' \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

curl 'https://imatag.com/api/v1/matches/web/?watermarked=true&date_gt=2018-08-01&date_lte=2018-08-02T12:45:00Z' \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

Query Parameters

Parameter Default Description
watermarked null If set to true, only watermarked results will be shown; if set to false, only non-watermarked results will be shown
exclusive null If set to true, only exclusive results will be shown; if set to false, only non-exclusive results will be shown
date null If set, only results found on that exact date (or exact date & time) will be shown. This cannot be combined with other date lookups (gt, lt, etc.)
date_lte null If set, only results found on that date or earlier will be shown
date_gte null If set, only results found on that date or later will be shown
date_lt null If set, only results found earlier than that date will be shown
date_gt null If set, only results found later than that date will be shown
blacklist null If set to true, only results from domain that are not in the blacklist will be returned (ie results for blacklisted domains are filtered out)

Response description

Attribute Description
count Total number of matches
next url of the next matches in the sequence (null if end is reached)
previous url of the previous matches in the sequence (null at the start)
results list of web match objects (see Web Match object) sorted by match date, newest first

Web Match Object

Attribute Description
url The URL of this match (direct link)
created The date of creation of the match (ISO8601)
type The type of match (always "web")
watermarked Whether the watermark was found (boolean)
exclusive If specified, whether the match if recorded for an exclusive image (optional boolean); at the time of the record
query_url The original URL of the query media
query_page_url The original URL of the page where the media was found
paths The list of corresponding media objects in your account (see Media object)
image The image object (see Image object) matched with the query

Press Matches

This endpoint lists all matches found in the press.

HTTP Request

GEThttps://imatag.com/api/v1/matches/press

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.get("https://imatag.com/api/v1/matches/press", headers=headers)
curl https://imatag.com/api/v1/matches/press/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created": "2018-08-03T12:35:23.371022Z",
            "issue": {},
            "page_number": 1,
            "paths": [
                {
                    "created": "2018-07-20T15:20:15.890934Z",
                    "image": "https://static2.imatag.com/54580,15ec6954eac4981b",
                    "path": "api.demo/images/new-york/brooklyn-bridge.jpeg",
                    "type": "image",
                    "url": "https://imatag.com/api/v1/media/api.demo/images/new-york/brooklyn-bridge.jpeg"
                }
            ],
            "type": "press",
            "url": "https://imatag.com/api/v1/matches/94457659/",
            "watermarked": true
        }
    ]
}

Query Parameters

Parameter Default Description
watermarked null If set to true, only watermarked results will be shown, if set to false, only non-watermarked results will be shown
date null If set, only results found on that exact date (or exact date & time) will be shown. This cannot be combined with other date lookups (gt, lt, etc.)
date_lte null If set, only results found on that date or earlier will be shown
date_gte null If set, only results found on that date or later will be shown
date_lt null If set, only results found earlier than that date will be shown
date_gt null If set, only results found later than that date will be shown

Response description

Attribute Description
count Total number of matches
next url of the next matches in the sequence (null if end is reached)
previous url of the previous matches in the sequence (null at the start)
results list of press match objects (see Press Match object) sorted by match date, newest first

Press Match Object

Attribute Description
url The URL of this match (direct link)
created The date of creation of the match (ISO8601)
type The type of match (always "press")
watermarked Whether the watermark was found or not (boolean)
issue Press issue where the media was found (see Press Issue object)
page_number Page of the issue where the image was found
paths The list of corresponding media objects in your account (see Media object)
image The image object (see Image object) matched with the query

Press Issue Object

Attribute Description
name Name of the publication
date Date of the publication (ISO8601, date only)

Credit Matches

This endpoint lists all matches found by matching your credit line(s).

HTTP Request

GEThttps://imatag.com/api/v1/matches/credit

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.get("https://imatag.com/api/v1/matches/credit", headers=headers)
curl https://imatag.com/api/v1/matches/credit/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
      {
         "url" : "https://imatag.com/api/v1/matches/credit/95998502/",
         "page_url" : "https://imatag.com/portfolio/secretan/sets/f9ea5e942684421eaefcf2967290a2a9/",
         "credit" : "© Thierry Secretan - DSCF2144.jpg - protected by IMATAG",
         "type" : "credit",
         "created" : "2018-01-23T16:39:31.569700Z",
         "image_url" : "http://static2.imatag.com/53538/090ddbea3e6aa622/2af10e0b4b84ee7313552e6e9bc9fa37-thierry-secretan-dscf2144jpg.jpg"
      },
      ...
    ]
}

Query Parameters

Parameter Default Description
date null If set, only results found on that exact date (or exact date & time) will be shown. This cannot be combined with other date lookups (gt, lt, etc.)
date_lte null If set, only results found on that date or earlier will be shown
date_gte null If set, only results found on that date or later will be shown
date_lt null If set, only results found earlier than that date will be shown
date_gt null If set, only results found later than that date will be shown
blacklist null If set to true, only results from domain that are not in the blacklist will be returned (ie results for blacklisted domains are filtered out)

Response description

Attribute Description
count Total number of matches
next url of the next matches in the sequence (null if end is reached)
previous url of the previous matches in the sequence (null at the start)
results list of press match objects (see Press Match object) sorted by match date, newest first

Text Match Object

Attribute Description
url The URL of this match (direct link)
created The date of creation of the match (ISO8601)
type The type of match (always "credit")
credit The credit found in the metadata of the image at image_url
image_url The URL of the image where the credit was found in its metadata
page_url The URL of the page where a reference to the image at image_url was found
image The image object (see Image object) matched with the query

Crawling

The crawling API controls web crawling specific web sites.

Crawling Session

A crawling session groups crawls of a website and defines the common parameters of those crawls. The first crawl is initiated (seeded) on the start_urls of the session. Links to pages internal to the domain are then added recursively to the list of pages to visit. Links to images are stored and visually matched to your media if the search option is enabled. Subsequent crawls start from the state of the latest crawl in the session and continue the crawling in a recursive manner.

Crawling Session Object

Attribute Description
url The URL of the session
id The unique identifier of the session
ctime Starting date of the session
mtime Modification date of the session (date of latest crawl)
stime Starting date of the last crawl
state State of the crawl (pending, running, failed, done or paused)
cycle_count Number of crawls performed on this session
crawl_delay Maximum duration of each crawl
search Whether to search for matches in your media
download_delay Delay between successive requests to the same domain
download_timeout Time to wait before assuming the connection timed out
start_urls List of urls the session was initiated on
batches URL of the list of crawling batches associated with the session (see Crawling Batch Object)

List all available sessions

HTTP Request

GEThttps://imatag.com/api/v1/crawling/sessions/

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.get("https://imatag.com/api/v1/crawling/sessions/", headers=headers)
curl https://imatag.com/api/v1/crawling/sessions/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
   "results" : [
      {
         "ctime" : "2018-08-09T12:19:57.849603+02:00",
         "download_timeout" : 15,
         "url" : "https://imatag.com/api/v1/crawling/sessions/1/",
         "stime" : "2018-08-09T12:19:57.849603+02:00",
         "mtime" : "2018-08-21T12:01:06.401858+02:00",
         "id" : 1,
         "download_delay" : 0.1,
         "search" : true,
         "batches" : "https://imatag.com/api/v1/crawling/sessions/1/batches/",
         "crawl_delay" : 300,
         "cycle_count" : 1,
         "start_urls" : [
            "https://imatag.com/"
         ]
      }
   ],
   "previous" : null,
   "next" : null
}

Query Parameters

Parameter Default Description
ctime null If set, only results found on that exact date on the ctime field (or exact date & time) will be shown. This cannot be combined with other date lookups on the same field (gt, lt, etc.)
ctime_lte null If set, only results found on that date or earlier on the ctime field will be shown
ctime_gte null If set, only results found on that date or later on the ctime field will be shown
ctime_lt null If set, only results found earlier than that date on the ctime field will be shown
ctime_gt null If set, only results found later than that date on the ctime field will be shown

Response description

Attribute Description
next url of the next sessions in the sequence (null if end is reached)
previous url of the previous sessions in the sequence (null at the start)
results list of Crawling Session objects (see Crawling Session object)

Get a session

This endpoint retrieves information about a specific crawling session.

HTTP Request

GEThttps://imatag.com/api/v1/crawling/sessions/<session_id>/

URL Parameters

Parameter Required Description
session_id true The unique id of the session to retrieve information on.
import requests

headers = {
    'Authorization': 'Token fd8fef6e430595edc3bab691d9a83230f0a56b99',
}
response = requests.get('https://imatag.com/api/v1/crawling/sessions/1/',
                        headers=headers)
curl https://imatag.com/api/v1/crawling/sessions/1/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
   "id" : 1,
   "batches" : "https://imatag.com/api/v1/crawling/sessions/1/batches/",
   "url" : "https://imatag.com/api/v1/crawling/sessions/1/",
   "mtime" : "2018-08-21T12:01:06.401858+02:00",
   "download_timeout" : 15,
   "start_urls" : [
      "https://imatag.com/"
   ],
   "stime" : "2018-08-09T12:19:57.849603+02:00",
   "ctime" : "2018-08-09T12:19:57.849603+02:00",
   "download_delay" : 0.1,
   "search" : true,
   "cycle_count" : 1,
   "crawl_delay" : 300
}

Response description

See Crawling Session object

Create a new session

HTTP Request

POSThttps://imatag.com/api/v1/crawling/sessions/

import requests

headers = {
    'Authorization': 'Token fd8fef6e430595edc3bab691d9a83230f0a56b99',
}
response = requests.post('https://imatag.com/api/v1/crawling/sessions/',
    json={'url': 'http://imatag.com' }, headers=headers)
curl https://imatag.com/api/v1/crawling/sessions/ \
  -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
  --data '{"url": "http://imatag.com"}'

The above command returns JSON structured like this:

{
   "mtime" : "2018-08-21T12:01:06.401858+02:00",
   "crawl_delay" : 300,
   "cycle_count" : 1,
   "download_timeout" : 15,
   "url" : "https://imatag.com/api/v1/crawling/sessions/1/",
   "ctime" : "2018-08-09T12:19:57.849603+02:00",
   "stime":"2018-08-09T12:19:57.849603+02:00"
   "id" : 1,
   "start_urls" : [
      "https://imatag.com/pour-entreprise/"
   ],
   "download_delay" : 1,
   "batches" : "https://imatag.com/api/v1/crawling/sessions/1/batches/",
   "search" : true
}

Request content

The content of the request must be JSON with following attributes:

Attribute Required Description
url true The URL to start crawling from.

Response description

See Crawling Session object

Delete an existing session

HTTP Request

DELETEhttps://imatag.com/api/v1/crawling/sessions/<session_id>/

URL Parameters

Parameter Required Description
session_id true The unique id of the session to delete.
import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.delete("https://imatag.com/api/v1/crawling/sessions/1/",
                           headers=headers)
curl -X DELETE \
  https://imatag.com/api/v1/crawling/sessions/1/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

Crawling Batch

A crawling batch stores information gathered during a crawl. Each time a crawl is run, a new crawling batch object is created at the end of it.

Crawling Batch Object

Attribute Description
url The URL of the crawling batch
id The unique identifier of the crawling batch
ctime Starting time at which the batch was created (end of crawl)
session A link to the crawling session associated with this batch (see Crawling Session object)
images Hash of information on the images found in the crawl, detailled below
images.count Number of images found in the crawl
images.log URL to download the list of images found during the crawl, in gzipped CSV format (optional)
images.tar URL to download the images found during the crawl, in TAR format (optional)
videos Hash of information on the videos found in the crawl, detailled below
videos.count Number of videos found in the crawl
videos.log URL to download the list of videos found during the crawl, in gzipped CSV format (optional)
documents Hash of information on the documents found in the crawl, detailled below
documents.count Number of documents found in the crawl
documents.log URL to download the list of documents found during the crawl, in gzipped CSV format (optional)
pages Hash of information on the pages found in the crawl, detailled below
pages.count Number of pages found in the crawl
pages.log URL to download the list of pages found during the crawl, in gzipped CSV format (optional)
pages.warc URL to download the requests and responses corresponding to pages found during the crawl, in gzipped WARC format (optional)
crawl_cycle session's cycle_count value at the time the batch was made (crawl number)

List the batches of a session

HTTP Request

GEThttps://imatag.com/api/v1/crawling/sessions/<session_id>/batches/

URL Parameters

Parameter Required Description
session_id true The unique id of the session to retrieve information on.
import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.get("https://imatag.com/api/v1/crawling/sessions/1/batches/", headers=headers)
curl https://imatag.com/api/v1/crawling/sessions/1/batches/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
   "results" : [
      {
         "pages" : {
            "log" : "https://static4.imatag.com/54688,17b90549bdefbf86",
            "count" : 213,
            "warc" : "https://static2.imatag.com/54666,17b9054be3fb1b12"
         },
         "session" : "https://imatag.com/api/v1/crawling/sessions/1/",
         "ctime" : "2018-08-21T12:04:25.660571+02:00",
         "images" : {
            "count" : 1092,
            "log" : "https://static4.imatag.com/54679,17b90530f4c665e4"
         },
         "crawl_cycle" : 1,
         "id" : 7154,
         "url" : "https://imatag.com/api/v1/crawling/batches/7154/"
      },
      ...
   ],
   "next" : null,
   "previous" : null
}

Query Parameters

Parameter Default Description
ctime null If set, only results found on that exact date on the ctime field (or exact date & time) will be shown. This cannot be combined with other date lookups on the same field (gt, lt, etc.)
ctime_lte null If set, only results found on that date or earlier on the ctime field will be shown
ctime_gte null If set, only results found on that date or later on the ctime field will be shown
ctime_lt null If set, only results found earlier than that date on the ctime field will be shown
ctime_gt null If set, only results found later than that date on the ctime field will be shown

Response description

Attribute Description
next url of the next batches in the sequence (null if end is reached)
previous url of the previous batches in the sequence (null at the start)
results list of Crawling Batch objects (see Crawling Batch object)

List all available batches

HTTP Request

GEThttps://imatag.com/api/v1/crawling/batches/

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.get("https://imatag.com/api/v1/crawling/batches/", headers=headers)
curl https://imatag.com/api/v1/crawling/batches/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
   "next" : null,
   "results" : [
      {
         "ctime" : "2018-08-13T15:51:23.186005+02:00",
         "session" : "https://imatag.com/api/v1/crawling/sessions/1/",
         "url" : "https://imatag.com/api/v1/crawling/batches/13/",
         "pages" : {
            "count" : 539,
            "warc" : "https://static3.imatag.com/54661,1729c1e94282b9aa",
            "log" : "https://static4.imatag.com/54686,1729c1e74e629d47"
         },
         "id" : 13,
         "crawl_cycle" : 1,
         "images" : {
            "count" : 2647,
            "log" : "https://static1.imatag.com/54682,1729c13dd6694192",
            "tar" : "https://static2.imatag.com/54662,1729c184b181ac39"
         }
      }
   ],
   "previous" : null
}

Query Parameters

Parameter Default Description
ctime null If set, only results found on that exact date on the ctime field (or exact date & time) will be shown. This cannot be combined with other date lookups on the same field (gt, lt, etc.)
ctime_lte null If set, only results found on that date or earlier on the ctime field will be shown
ctime_gte null If set, only results found on that date or later on the ctime field will be shown
ctime_lt null If set, only results found earlier than that date on the ctime field will be shown
ctime_gt null If set, only results found later than that date on the ctime field will be shown

Response description

Attribute Description
next url of the next batches in the sequence (null if end is reached)
previous url of the previous batches in the sequence (null at the start)
results list of Crawling Batch objects (see Crawling Batch object)

Get a batch

import requests

headers = {
    'Authorization': 'Token fd8fef6e430595edc3bab691d9a83230f0a56b99',
}
response = requests.get('https://imatag.com/api/v1/crawling/batches/13/',
                        headers=headers)
curl https://imatag.com/api/v1/crawling/batches/13/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
   "id" : 13,
   "crawl_cycle" : 1,
   "pages" : {
      "log" : "https://static1.imatag.com/54686,1729c1e74e629d47",
      "warc" : "https://static4.imatag.com/54661,1729c1e94282b9aa",
      "count" : 539
   },
   "session" : "https://imatag.com/api/v1/crawling/sessions/1/",
   "images" : {
      "log" : "https://static1.imatag.com/54682,1729c13dd6694192",
      "count" : 2647
   },
   "url" : "https://imatag.com/api/v1/crawling/batches/13/",
   "ctime" : "2018-08-13T15:51:23.186005+02:00"
}

This endpoint retrieves information about a specific crawling batch.

HTTP Request

GEThttps://imatag.com/api/v1/crawling/batches/<batch_id>/

URL Parameters

Parameter Required Description
batch_id true The unique id of the batch to retrieve information on.

Response description

See Crawling Batch object

Searches

The searches endpoint allows you to schedule searches on images and, depending on your pricing plan, PDF documents. It also allows you to monitor the status of these searches and once complete, to access their results. Searches scheduled via the API, like automated web and press search will find watermarked and similar matches.

Search object

Searches may be done synchronously or asynchronously depending on the input media type and the expected time required to perform the search.

Synchronous searches are ephemeral and never recorded, but are faster than asynchronous searches.

For syncronous searches, the search object contains only the following fields:

Field Description
status The status of the search. Can be: complete or failed
matches When status is complete, the URL of the list of matches (see Web Match object) found in this search; for synchronous searches, the matches list is inlined instead

For asynchronous searches, the status may take the additional values of pending, in progress, or cancelled, and the following additional fields are avaiable:

Field Description
progress When status is in progress, an integer representing advancement (in percent).
url The URL of the search
name The name of the search
created The date of creation of the search
type The type of object: image or document
image For image, the static URL of the image.
document For document, the static URL of the document.

List all previous searches

This endpoint lists the asynchronous searches submitted by the user.

import requests

headers = {
    'Authorization': 'Token fd8fef6e430595edc3bab691d9a83230f0a56b99',
}
response = requests.get('https://imatag.com/api/v1/searches/', headers=headers)
curl https://imatag.com/api/v1/searches/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "next": null,
    "previous": null,
    "results": [
        {
            "url": "https://imatag.com/api/v1/searches/qYh98JhK3mUa/",
            "type": "image",
            "image": "https://static1.imatag.com/172987,20d82c6c92e0ff2a",
            "name": "https://imatag.com/api/doc/images/tour-eiffel.jpeg",
            "created": "2018-11-08T16:48:11.619025Z",
            "status": "complete",
            "matches": "https://imatag.com/api/v1/searches/qYh98JhK3mUa/matches/"
        },
        {
            "url": "https://imatag.com/api/v1/searches/HTnqefQkb7jq/",
            "type": "image",
            "image": "https://static2.imatag.com/176044,20b70be705dcf657",
            "name": "tour-eiffel.jpg",
            "created": "2018-11-07T13:25:52.277479Z",
            "status": "complete",
            "matches": "https://imatag.com/api/v1/searches/HTnqefQkb7jq/matches/"
        }
    ]
}

HTTP Request

GEThttps://imatag.com/api/v1/searches

Query Parameters

Parameter Default Description
date null If set, only searches started on that exact date on the date field (or exact date & time) will be shown. This cannot be combined with other date lookups on the same field (gt, lt, etc.)
date_lte null If set, only searches started on that date or earlier on the date field will be shown
date_gte null If set, only searches started on that date or later on the date field will be shown
date_lt null If set, only searches started earlier than that date on the date field will be shown
date_gt null If set, only searches started later than that date on the date field will be shown

Response description

Attribute Description
next url of the next searches in the sequence (null if end is reached)
previous url of the previous searches in the sequence (null at the start)
results list of Search objects (see Search object)

This endpoint retrieves a specific search.

import requests

headers = {
    'Authorization': 'Token fd8fef6e430595edc3bab691d9a83230f0a56b99',
}
response = requests.get('https://imatag.com/api/v1/searches/HTnqefQkb7jq',
                        headers=headers)
curl hhttps://imatag.com/api/v1/searches/HTnqefQkb7jq \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "url": "https://imatag.com/api/v1/searches/HTnqefQkb7jq/",
    "type": "image",
    "image": "https://static2.imatag.com/176044,20b70be705dcf657",
    "name": "tour-eiffel.jpg",
    "created": "2018-11-07T13:25:52.277479Z",
    "status": "complete",
    "matches": "https://imatag.com/api/v1/searches/HTnqefQkb7jq/matches/"
}

HTTP Request

GEThttps://imatag.com/api/v1/searches/<search_id>/

Response description

See Search object

You can download the registered tour-eiffel.jpeg file from the media example to run the example.

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
    "Content-Type": "image/jpeg",
}
files = {'file': open('tour-eiffel.jpeg', 'rb')}
response = requests.post("https://imatag.com/api/v1/searches/",
                        files=files, headers=headers)

curl -X POST \
  https://imatag.com/api/v1/searches/ \
  -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
  -F "file=@tour-eiffel.jpeg"

The above commands returns JSON structured like this:

{
    "url": "https://imatag.com/api/v1/searches/HTnqefQkb7jq/",
    "type": "image",
    "image": "https://static2.imatag.com/176044,20b70be705dcf657",
    "name": "tour-eiffel.jpg",
    "created": "2018-11-07T13:25:52.277479Z",
    "status": "pending"
}

alternatively you can perform a request by url

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
    "Content-Type": "application/json",
}
data = {'url': 'https://imatag.com/api/doc/images/tour-eiffel.jpeg'}
response = requests.post("https://imatag.com/api/v1/searches/",
                        data=data, headers=headers)

curl -X POST \
  https://imatag.com/api/v1/searches/ \
  -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
  -F "url=https://imatag.com/api/doc/images/tour-eiffel.jpeg"

The above commands returns JSON structured like this:

{
    "url": "https://imatag.com/api/v1/searches/2ugF64RJDDwX/",
    "type": "image",
    "name": "tour-eiffel by url",
    "created": "2018-11-08T14:58:51.539193Z",
    "status": "pending"
}

This endpoint performs a new search from an image, either by uploading it or by providing a publicly accessible url. Depending on your pricing plan, you might be allowed to upload pdf files to search all images in the document. You might also be limited in speed and number of searches.

HTTP Request

POSThttps://imatag.com/api/v1/searches/

Query Parameters

Parameter Default Description
url null If set, the url of the query image or document. Mutually exclusive with file upload.
file null If set, the query file (image or document). Mutually exclusive with url.
name null If set, name for the search. If unset, the url or the uploaded file name will be used.
sync Run the search in synchronous mode if set; default is true for images, false otherwise; synchronous searches are allowed only on images
category null Where to search; for images the default may be changed to one of private (your own images), web (all the images we crawled on the Web), or web_credited (the images we crawled on the Web with a credit)
similar If set, disable geometry validation and watermark check; faster search; default is true when category is web or web_credited, false otherwise

Response content

If the request is succesful, the response is a Search object. HTTP status code is 201 for asynchronous requests and 200 for synchronous requests.

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.delete("https://imatag.com/api/v1/searches/trhPnufS7NxJ/",
                           headers=headers)
curl -X DELETE \
  https://imatag.com/api/v1/media/api.demo/searches/trhPnufS7NxJ/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

This endpoint deletes an existing search and associated matches.

HTTP Request

DELETEhttps://imatag.com/api/v1/searches/<search_id>/

Classification

Image Classifiers

This endpoint performs image classification based on Deep Learning models.

Classifier Object

Attribute Description
name Name of the classifier
num_classes Number of different output classes
image_size Maximum supported image size (larger images will be resized, with no gain in classification performance)

A classifier determines to which classes an image belong by analyzing its pixels. It returns the most likely classes the image belongs to, along with an approximate probability of belonging to each class.

List all available classifiers

HTTP Request

GEThttps://imatag.com/api/v1/classifiers/

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.get("https://imatag.com/api/v1/classifiers/", headers=headers)
curl https://imatag.com/api/v1/classifiers/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "next":null,
    "previous":null,
    "results":[
        {
            "name": "mxnet-resnet-152-10k",
            "num_classes": 10731,
            "image_size": 224
        },
        {
            "name": "tensorrt-resnet-50-yahoo-opennsfw",
            "num_classes": 2,
            "image_size": 224
        },
        {
            "name":"tensorrt-inception3-6k",
            "num_classes":6012,
            "image_size":299
        }
    ]
}

Response description

Attribute Description
next url of the next matches in the sequence (null if end is reached)
previous url of the previous matches in the sequence (null at the start)
results list of classifier objects (see Classifier object)

Get a classifier

import requests

headers = {
    'Authorization': 'Token fd8fef6e430595edc3bab691d9a83230f0a56b99',
}
response = requests.get('https://imatag.com/api/v1/classifiers/tensorrt-inception3-6k/',
                        headers=headers)
curl https://imatag.com/api/v1/classifiers/tensorrt-inception3-6k/ \
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "name": "tensorrt-inception3-6k",
    "num_classes": 6012,
    "image_size": 299
}

This endpoint retrieves information about a classifier.

HTTP Request

GEThttps://imatag.com/api/v1/classifiers/<classifier_name>/

URL Parameters

Parameter Required Description
classifier_name true The name of the classifier to retrieve information on.

Response description

See Classifier object

Perform classification on an image

import requests

# perform classification by direct upload 
headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
    "Content-Type": "image/jpeg",
}
image = open("./tour-eiffel.jpeg", "rb").read()
response = requests.post("https://imatag.com/api/v1/classifiers/tensorrt-inception3-6k/",
                         data=image, headers=headers)

# perform classification by image URL
headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
data = {
    "url": "https://imatag.com/api/doc/images/tour-eiffel.jpeg"
}
response = requests.post("https://imatag.com/api/v1/watermarking/",
                         json=data, headers=headers)
# perform classification by direct upload
curl -X POST \
https://imatag.com/api/v1/classifiers/tensorrt-inception3-6k/ \
-H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
-H "Content-Type: image/jpeg" \
--data-binary @- < tour-eiffel.jpeg

# perform classification by image URL 
curl -X POST \
https://imatag.com/api/v1/classifiers/tensorrt-inception3-6k/ \
-H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
-H "Content-Type: application/json" \
--data '{"url": "https://imatag.com/api/doc/images/tour-eiffel.jpeg"}'

The above command returns JSON structured like this:

{
    "tags":
        {
            "fr": [
                {
                    "tag": "point de repère",
                    "prob": 0.79
                },
                {
                    "tag": "nuit",
                    "prob": 0.65
                },
                ...
            ],
            "en": [
                {
                    "tag": "landmark",
                    "prob": 0.79
                },
                {
                    "tag": "night",
                    "prob": 0.65
                },
                {
                    "tag": "tower",
                    "prob": 0.63
                },
                ...
            ]
        }
}

This endpoint performs classification on the uploaded image using the classifier.

You can download this file to run the example.

HTTP Request

POSThttps://imatag.com/api/v1/classifiers/<classifier_name>/

URL Parameters

Parameter Required Description
classifier_name true The name of the classifier to use for classification.

Request content

The content of the request must be either:

Response description

Attribute Description
tags Hash of sorted list of tag objects (see Tag object) associated with the image, with one list for each supported language ("en", "fr" at the moment).

Tag Object

Attribute Description
tag The description of the tag
prob The probability that this image has this tag

Watermarking

The watermarking endpoint allows you to apply an invisible watermark on a file. The watermarked file can then be:

The following files are sported:

Watermarking a file

Watermarking by URL

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
data = {
    "url": "https://imatag.com/api/doc/images/tour-eiffel.jpeg",
    "media" : "image", # image, video, ... (default image)
    "sync": True, # False (default true)
    "timeout" : 120 # number of seconds (default 120)
}
response = requests.post("https://imatag.com/api/v1/watermarking/",
                         json=data, headers=headers)    
curl -X POST \
  https://imatag.com/api/v1/watermarking/ \
  -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
  -H "Content-Type: application/json" \
  --data '{"url": "https://imatag.com/api/doc/images/tour-eiffel.jpeg", "media": "image", "sync": true}'

The above command returns JSON structured like this:

{
    "expiry": "2018-12-06T17:26:22Z",
    "original": "http://static1.imatag.com/208141,240d162ab9716c41",
    "watermarked": "http://static2.imatag.com/208141,240d164028af21c7"
}

HTTP Request

POSThttps://imatag.com/api/v1/watermarking/

Request content

The content of the request must be either:

Response description

The response indicates where to download the generated assets and their expiration.

Attribute Description
original The URL of the original full-size image
watermarked The URL of the watermarked full-size image
expiry Expiration date of the watermarked assets on our servers (approximate)

Limited number of watermarking per day

This endpoint has extra rate limits, to allow a maximum number of the watermarking endpoint calls per day i.e. per 24-hours period. The limit & remaining counts are indicated as response headers:

Watermark an image

Watermarking image by direct upload

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
    "Content-Type": "image/jpeg",
}
img = open("./original.jpeg", "rb").read() # file to watermark
response = requests.post("https://imatag.com/api/v1/watermarking/",
                         data=img, headers=headers)
curl -X POST \
  https://imatag.com/api/v1/watermarking/ \
  -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
  -H "Content-Type: image/jpeg" \
  --data-binary @- < ./original.jpeg

The endpoint apply the watermarking on any image, provided in a supported format. See the list of supported formats

Response description

Response description

{
  "registration": "http://static4.imatag.com/208145,240d163d6fdc2249"
}

Image will have additional returns:

Attribute Description
registration The URL of the registration data that should be sent on the media endpoint

Watermark a video

Request content

Video will have additional JSON parameters:

Detect a watermarked file

Watermark detection

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
data = {
    "query": "https://imatag.com/api/doc/images/query.jpeg",
    "registration": "https://imatag.com/api/doc/images/registration.lmk",
}
response = requests.post(
    "https://imatag.com/api/v1/watermarking/detect/",
    json=data, headers=headers)
curl -X POST \
  https://imatag.com/api/v1/watermarking/detect/ \
  -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
  -H "Content-Type: application/json" \
  --data '{"query": "https://imatag.com/api/doc/images/query.jpeg",
  "registration": "https://imatag.com/api/doc/images/registration.lmk"}'

The above command returns JSON structured like this:

{
    "marked": true
}

HTTP Request

POSThttps://imatag.com/api/v1/watermarking/detect/

The endpoint allows to verify if an image a.k.a query is a watermarked copy of the image from the registration file and optionally the original image (in case of Transactional watermarking)

Request content

The content of the request must be JSON with following attributes:

Attribute Required Description
query true The URL of the image to check
sync false the sync call of the api (true or false, default = true)
timeout false the timeout call of the api (0 <= integer <= 120, default = 120)
media false the type of media to detect (image or video, default = image)

Response description

The response indicates whether the query image is a watermarked copy of the compared registration/original asset(s).

Attribute Description
marked If True, the query is watermarked.
If False, the query is either too much altered or a different image.

Image

Request content

Image will have additional JSON parameters:

Attribute Required Description
original false The URL of the original image matching the transactional registration file.
registration true The URL of the registration file (containing the watermark data) for comparison against the query

Video

Request content

Video will have additional JSON parameters:

Attribute Required Description
original true The URL of the original image matching the transactional registration file.
secret true the secret used during the water marking process

Get the encryption key

Get the encryption key

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.get(
    "https://imatag.com/api/v1/watermarking/key/",
    headers=headers)
curl https://imatag.com/api/v1/watermarking/key/
 -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "key": "-----BEGIN RSA PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DIDAQAB\n-----END RSA PUBLIC KEY-----"
}

HTTP Request

GEThttps://imatag.com/api/v1/watermarking/key/

This endpoint returns the encryption key that can be used by the watermarking software to encrypt the registration file.

Response description

The response contains the key.

Attribute Description
key The RSA public key in PEM format

Watermarking Software

Depending on your service plan, you might have access to the IMATAG watermarking software. It is used to watermark your images before registering them on the API media endpoint. This enables you to have the fastest possible watermarking pipeline, as well as making your delivery process independent from any IMATAG API calls, ensuring the highest possible reliability.

Download

Go to your IMATAG account and scroll down to the "Watermarking software" section.

Installation

No installation is needed. The software you downloaded is a binary which can be executed to watermark images directly. It has no dependencies.

Before execution, you will have to make sure that:

Software usage

Assuming your current directory contains lamark, public_key.derand input_image.jpg

import subprocess

subprocess.check_call(["lamark",
                       "input_image.jpg",
                       "output_image.jpg", "registration.lmk",
                       "public_key.der"])
./lamark input_image.jpg output_image.jpg registration.lmk public_key.der

The above should produce the following output

LAMARK image watermarking tool 2.3.4
Copyright 2015-2018 Lamark

This software is based in part on the work of the Independent JPEG Group
Using fdlibm Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.

And create output_image.jpg and registration.lmk in your current directory.

lamark [options] <input_image.jpg> <output_image.jpg> <registration.lmk> <public_key.der>

pameters Description
<input_image.jpg> The full-resolution input image, in JPEG format
<output_image.jpg> The full-resolution output wartermarked image, in JPEG format
<registration.lmk> The encrypted registration data that should be sent on the media endpoint
<public_key.der> The encryption key downloaded from your IMATAG account. Used to encrypt the registration file
options Description
-t Transactional watermarking

Output and exit codes

The software always outputs version and licence information on stderr

Advanced usage: Transactional watermarking

./lamark    input_image.jpg output_image_1.jpg registration_1.lmk public_key.der
./lamark -t input_image.jpg output_image_2.jpg registration_2.lmk public_key.der

The "Transactional watermarking" -t option can be used to limit storage and bandwidth usage if you watermark the same original image many times. The drawback is that it will make your scripts stateful and generally more complex.

It works like this: the first time you watermark an image, do not use the -t option and register the registration.lmk file. When you watermark the same image again, add the -t option. This will make the new registration.lmk file much smaller. You can register it as usual.

What happens is that the normal or in this case the first registration.lmk file contains a smaller version of your image which is used by our servers to identify your image (it is also used to generate thumbnails for the web interface). If you watermark the same image again, you don't need to send it again and the -t option allows you not to. To identify the original we compute a hash of its pixels and which is included in the registration.lmk file. When we register a transactional registration.lmk, we find the file which was already registered with the same hash and use that one. This means that if you haven't registered the first one or have modified it's content in any way since then, you will get an error when you try to register the transactional registration.lmk. Note that we look at the pixel data so if you modify only the metadata you should be OK.

Uploads

The uploads endpoint allows you to store temporarily your images on our servers, in order to use our API with the image URL instead of re-posting the same image content on multiple endpoints.

Upload an image

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
    "Content-Type": "image/jpeg",
}
img = open("./original.jpeg", "rb").read()
response = requests.post(
    "https://imatag.com/api/v1/uploads/",
    data=img, headers=headers)
curl -X POST \
  https://imatag.com/api/v1/uploads/ \
  -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
  -H "Content-Type: image/jpeg" \
  --data-binary @- < ./original.jpeg

The above command returns JSON structured like this:

{
    "expiry": "2018-12-28T14:10:24Z",
    "url": "http://static2.imatag.com/208562,27981f5f5ad9e3de"
}

This endpoints stores the image on our servers in a temporary collection.

HTTP Request

POSThttps://imatag.com/api/v1/uploads/

Response description

The response indicates where to download the uploaded assets and its expiration.

Attribute Description
url The URL of the uploaded image on our servers
expiry Expiration date of the uploaded image on our servers (approximate)

Account

Account settings

This endpoint allows you to check your account settings and status.

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.get(
    "https://imatag.com/api/v1/account/",
    headers=headers)
curl -X GET \
  https://imatag.com/api/v1/account/ \
  -H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "username": "api.demo",
    "email": "support@imatag.com",
    "full_name": "api demo",
    "service_plan": "Starter",
    "incidents": null,
    "image_count": 9,
    "image_quota": 50,
    "disk_quota": 13030726,
    "disk_usage": 2544966
}

HTTP Request

GEThttps://imatag.com/api/v1/account/

Response description

Attribute Description
username name of the account (cannot be modified)
full_name company name or first name & last name
email the email address used for login & contact
service_plan the currently subscribed payment plan
incidents current incidents on the account (null if none). See below for incidents description.
image_count current number of images owned by the user
image_quota maximum number of images based on the current service plan (null if no maximum)
disk_usage current disk usage of the user (in bytes)
disk_quota maximum disk usage based on the current service plan (null if no maximum)
account_expires only in case of certain incidents, the date at which the account will be deleted

incidents

description of the incidents

Value Description
null no incident
free trial expired the user subscribed to a free trial and it has expired ("expires" will be set)
payment overdue the user currently is currently subscribed to a non-free plan and their last payment has not come through ("expires" will be set)
quota exceeded the current number of images owned by the user exceeds their quota or their disk usage exceed their disk quota

API key

import requests

data = {
    "username": "api.demo",
    "password": "*********",
}
response = requests.post(
    "https://imatag.com/api/v1/account/token/",
    json=data)
curl -X POST \
https://imatag.com/api/v1/account/token/ \
-H "Content-Type: application/json" \
--data '{"username": "api.demo", "password": "*********"}'

The above command returns JSON structured like this:

{
    "token": "fd8fef6e430595edc3bab691d9a83230f0a56b99",
}

This endpoint (generates and) return an API key, that shall be used for any other API call, for a user with valid IMATAG credentials.

HTTP Request

POSThttps://imatag.com/api/v1/account/token

Query Parameters

Parameter Description
username Valid username or email address for authentication
password Valid password for authentication

Domains

Domain object

The representation of a domain is fairly simple

Attribute Description
url domain name with extention (eg imatag.com); protocol is not necessary.

Domain blacklist

This endpoint allows to manage a blacklist of domains. Matches recorded on blacklisted domains will be ignored (filtered out).

Add a domain to the baclkist

Add a domain to the blacklist:

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
data = {
    "url": "imatag.com"
}
response = requests.post(
    "https://imatag.com/api/v1/domains/blacklist",
    json=data, headers=headers)

curl -X POST \
https://imatag.com/api/v1/domains/blacklist/ \
-H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
-H "Content-Type: application/json" \
--data '{"url": "imatag.com"}'

This endpoint allows to add a domain to the blacklist

HTTP Request

POSThttps://imatag.com/api/v1/domains/blacklist/

Get the domain blacklist

Get the domain blacklist:

import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
}
response = requests.get(
    "https://imatag.com/api/v1/domains/blacklist",
    headers=headers)
curl -X GET \
https://imatag.com/api/v1/domains/blacklist/ \
-H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

The above command returns JSON structured like this:

{
    "next": null,
    "previous": null,
    "results": [
        {
            "url": "imatag.com"
        }
    ]
}

This endpoint allows to retrieve all domains that are in the blacklist

HTTP Request

GEThttps://imatag.com/api/v1/domains/blacklist/

Removes a domain from the blacklist

Removes a domain from the backlist:

import json
import requests

headers = {
    "Authorization": "Token fd8fef6e430595edc3bab691d9a83230f0a56b99",
    'Content-Type': 'application/json',
}
data = {
    "url": "imatag.com"
}
response = requests.delete(
    "https://imatag.com/api/v1/domains/blacklist",
    data=json.dumps(data), headers=headers)
curl -X DELETE \
https://imatag.com/api/v1/domains/blacklist/ \
-H "Authorization: Token fd8fef6e430595edc3bab691d9a83230f0a56b99" \
-H "Content-Type: application/json" \
--data '{"url": "imatag.com"}'

This endpoint allows to removes a domain from the backlist

HTTP Request

DELETEhttps://imatag.com/api/v1/domains/blacklist/

API Workflows

This section provides information about more complex workflows using our API depending on some use cases.

Register a watermarked image

import requests
TOKEN = "Token fd8fef6e430595edc3bab691d9a83230f0a56b99"

# upload my image to imatag
headers = {"Authorization": TOKEN, "Content-Type": "image/jpeg"}
img = open("./original.jpeg", "rb").read()
response = requests.post(
    "https://imatag.com/api/v1/uploads/",
    data=img, headers=headers)
uploaded_url = response.json()['url']

# watermark the uploaded image
headers = {"Authorization": TOKEN}
data = {"url": uploaded_url}
response = requests.post(
    "https://imatag.com/api/v1/watermarking/",
    json=data, headers=headers)
resp_data = response.json()
watermarked_image = resp_data['watermarked']
registration_file = resp_data['registration']

# register the watermarked image in my media
headers = {"Authorization": TOKEN, "Content-Type": "application/json"}
data = {"url": registration_file}
requests.put(
    "https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg",
    data=json.dumps(data), headers=headers)

For many photographers, tracking illegal use of their images is important. This workflow explains the steps to watermark then register an image into the user account: