Introduction
Welcome to the IMATAG API v1!
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.
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:
- 10 requests per second.
- 50,000 requests per day (ie. per 24-hours period).
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.
X-Rate-Limit-<Period>
: The number of API requests that are allowed for the period.X-Rate-Limit-<Period>-Remaining
: The number of API requests still allowed for the current period. where<Period>
can be: Secondly, Minutely, Hourly, Daily.
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 a 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 <your api token>
.
This account contains CC0-watermarked images that were uploaded and tracked on the Internet via our crawlers for demo purposes (to find similar or watermarked copies). You'll be able to see these images & track their detected usage via the API.
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 |
API Endpoints
Below is the list of all available endpoints & their full description: this is API time!
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 but not yet developed. 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. |
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:
- we register its watermarking key and will therefore be able to detect its presence;
- we will search for it on the web, in the press, etc. depending on your account settings.
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 its watermark even from a manual query.
Media are organized in a folder tree structure. There are few constraints on the folder structure/naming:
- Unless you have specific privileges, the root of the tree is always your
homedir
. - Below that, you can make the structure as flat or as deep as you need to match your own media structure or to make it easy to manage. (If you are a Digital Asset Manager, see the note below)
- You can use file extensions in the filename of your media but you don't have to, a straight UUID or any other
internal reference of yours will work just as well. We have included file extensions in this documentation examples
to make it more obvoius whether we are talking of a
folder
or amedia
. - you can't use "/" in the folder or media names as it is reserved for folder hierarchy.
- you can use unicode, but keep in mind the following points
- you will (obviously) need to URL-encode the path, so if you avoid using any character which need to be URL-encoded, you will save yourself some trouble.
- We encourage you to avoid using white-space characters and any other character which might be invisible or ambiguous when displayed.
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 <your api token>',
}
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 <your api token>"
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
GET
https://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 <your api token>',
}
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 <your api token>"
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
GET
https://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 <your api token>",
"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 <your api token>" \
-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
PUT
https://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:
- the full binary content of the LMK file, generated by the watermarking software. The content-type of the request must be
application/lmk
. - the URL of the asset as JSON data:
{"url": "http://..."}
, generated by the watermarking endpoint. The content-type of the request must beapplication/json
.
Response description
If the request is successful, the response is the newly created Media object
Register non-watermarked file for similar tracking only
import requests
headers = {
"Authorization": "Token <your api token>",
"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 <your api token>" \
-H "Content-Type: image/jpeg" \
--data-binary @- < ./tour-eiffel.jpeg
curl -X PUT \
https://imatag.com/api/v1/media/api.demo/uploads/2018/my-image.jpg \
-H "Authorization: Token <your api token>" \
-H "Content-Type: application/json" \
--data '{"url" : "https://some.website.com/media/my-image.jpg"}'
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 file as a new media. The request is similar to the default media creation, except the content shall be an image or video directly.
This allows limited features with uploaded images, compared to watermarked media. Files can only be searched for other file with similar visual content:
- No watermark detection will be performed
- No guarantee in matches found (the image found looks like the original but it might be a copy/use of the original or a different one)
For example, similar visual content images can produce matches for the same-looking but different photos, as shown below:
Supported format
file type | content type | content |
---|---|---|
image | application/json | {"url": "url/of/file.jpg"} |
image | image/jpg | binary file |
video | application/json | {"url": "url/of/file.mp4"} |
video | video/mp4 | binary file |
Request content
The content of the request must be either:
- the full binary content of the file. The Content-Type header must be set according to the file format.
- the URL of the asset as JSON data:
{"url": "http://..."}
, returned by the temporary upload endpoint or the URL of the remote image for small images only (<5Mb). The content-type of the request must beapplication/json
.
Response description
If the request is successful, the response is the newly created Media object
Register an exclusive image
import requests
headers = {
"Authorization": "Token <your api token>",
"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 <your api token>" \
-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,
- using the optional boolean
X-Lamark-Exclusive
header, when putting the media as binary content - using the optional boolean
exclusive
attribute in json data
Delete an existing media
import requests
headers = {
"Authorization": "Token <your api token>",
}
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 <your api token>"
This endpoint deletes and unregisters an existing media.
HTTP Request
DELETE
https://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 extension of the media to delete |
Create a folder
import requests
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "application/x-directory",
}
response = requests.put(
"https://imatag.com/api/v1/media/api.demo/uploads/2018",
headers=headers,
)
curl -X PUT \
https://imatag.com/api/v1/media/api.demo/uploads/2018 \
-H "Authorization: Token <your api token>" \
-H "Content-Type: application/x-directory"
This endpoint creates an empty folder.
HTTP Request
PUT
https://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). |
Delete an existing folder
import requests
headers = {
"Authorization": "Token <your api token>",
}
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 <your api token>"
This endpoint deletes a folder and all of its content (subfolders, images, documents, etc.) recursively. All media contained within will be unregistered.
HTTP Request
DELETE
https://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). |
Move a folder or a media
import requests
headers = {
"Authorization": "Token <your api token>",
}
data = {
"url": "https://imatag.com/api/v1/media/<homedir>/<path>",
"to" : "url": "https://imatag.com/api/v1/media/<homedir>/<other path>",
}
response = requests.post("https://imatag.com/api/v1/media/_move",
json=data, headers=headers)
The above command returns JSON structured like this:
{
"path": "<homedir>/<path>"
}
url
need to be a valid URLto
will be created if needed- if
to
ends with a/
it is considered as a folder where the content ofurl
will be place - in other case
url
will be rename toto
- if
path
is the new url of the moved/renamed path
HTTP Request
POST
https://imatag.com/api/v1/media/_move
Request content
url | to |
---|---|
the url to change | the future new url |
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 depends 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 |
credit | credit of the image (null if unavailable) |
thumbnail | URL where to find a thumbnail of the image (null if unavailable) |
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
GET
https://imatag.com/api/v1/matches/web
import requests
headers = {
"Authorization": "Token <your api token>",
}
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 <your api token>"
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 <your api token>"
The above command returns JSON structured like this:
{
"count": 36858,
"next": "https://imatag.com/api/v1/matches/web/?cursor=cD0xNTczNTgwNTgyNzQ5JmM9MzY4NTg%3D",
"previous": null,
"results": [
{
"url": "https://imatag.com/api/v1/matches/190113962/",
"created": "2019-11-13T13:59:09.665391Z",
"type": "web",
"watermarked": false,
"query_url": "http://p-umc.com/wp-content/uploads/slz-live-setting/boxed-bg-img-03.jpg",
"query_page_url": "http://p-umc.com/sermon/the-invitation-is-to-all-a-wesley-hymn-devotion-for-lent/",
"paths": [
{
"url": "https://imatag.com/api/v1/media/api.demo/images/new-york/nyc-taxis.jpeg",
"path": "api.demo/images/new-york/nyc-taxis.jpeg",
"created": "2018-07-20T15:20:15.880679Z",
"disk_usage": 234523,
"type": "image",
"thumbnail": "https://static2.imatag.com/206837,8110da3066effc82",
"image": "https://static4.imatag.com/54578,15ec695538df826a",
"web_matches": "https://imatag.com/api/v1/media/api.demo/images/new-york/nyc-taxis.jpeg/_matches/web/",
"press_matches": "https://imatag.com/api/v1/media/api.demo/images/new-york/nyc-taxis.jpeg/_matches/press/",
}
],
"image": {
"type": "registered",
"url": "https://static4.imatag.com/54578,15ec695538df826a",
"width": 1280,
"height": 853,
"thumbnail": "https://static1.imatag.com/206837,8110da3066effc82",
"credit": null
}
},
"..."
]
}
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) |
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
GET
https://imatag.com/api/v1/matches/press
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v1/matches/press", headers=headers)
curl https://imatag.com/api/v1/matches/press/ \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"url": "https://imatag.com/api/v1/matches/94457659/",
"created": "2018-08-03T12:35:23.371022Z",
"type": "press",
"watermarked": true,
"issue": {},
"page_number": 1,
"paths": [
{
"url": "https://imatag.com/api/v1/media/api.demo/images/new-york/brooklyn-bridge.jpeg",
"path": "api.demo/images/new-york/brooklyn-bridge.jpeg",
"created": "2018-07-20T15:20:15.890934Z",
"disk_usage": 293648,
"type": "image",
"thumbnail": "https://static4.imatag.com/211697,70014e5e3e082b02",
"image": "https://static2.imatag.com/54580,15ec6954eac4981b",
"web_matches": "https://imatag.com/api/v1/media/api.demo/images/new-york/brooklyn-bridge.jpeg/_matches/web/",
"press_matches": "https://imatag.com/api/v1/media/api.demo/images/new-york/brooklyn-bridge.jpeg/_matches/press/",
}
],
"image": {
"type": "registered",
"url": "https://static2.imatag.com/54580,15ec6954eac4981b",
"width": 1280,
"height": 904,
"thumbnail": "https://static3.imatag.com/211697,70014e5e3e082b02",
"credit": null
},
]
}
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
GET
https://imatag.com/api/v1/matches/credit
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v1/matches/credit", headers=headers)
curl https://imatag.com/api/v1/matches/credit/ \
-H "Authorization: Token <your api token>"
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
GET
https://imatag.com/api/v1/crawling/sessions/
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v1/crawling/sessions/", headers=headers)
curl https://imatag.com/api/v1/crawling/sessions/ \
-H "Authorization: Token <your api token>"
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
GET
https://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 <your api token>',
}
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 <your api token>"
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
Create a new session
HTTP Request
POST
https://imatag.com/api/v1/crawling/sessions/
import requests
headers = {
'Authorization': 'Token <your api token>',
}
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 <your api token>" \
--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
Delete an existing session
HTTP Request
DELETE
https://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 <your api token>",
}
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 <your api token>"
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, detailed 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, detailed 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, detailed 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, detailed 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
GET
https://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 <your api token>",
}
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 <your api token>"
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
GET
https://imatag.com/api/v1/crawling/batches/
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v1/crawling/batches/", headers=headers)
curl https://imatag.com/api/v1/crawling/batches/ \
-H "Authorization: Token <your api token>"
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 <your api token>',
}
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 <your api token>"
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
GET
https://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
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 <your api token>',
}
response = requests.get('https://imatag.com/api/v1/searches/', headers=headers)
curl https://imatag.com/api/v1/searches/ \
-H "Authorization: Token <your api token>"
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
GET
https://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) |
Get a search
This endpoint retrieves a specific search.
import requests
headers = {
'Authorization': 'Token <your api token>',
}
response = requests.get('https://imatag.com/api/v1/searches/HTnqefQkb7jq',
headers=headers)
curl hhttps://imatag.com/api/v1/searches/HTnqefQkb7jq \
-H "Authorization: Token <your api token>"
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
GET
https://imatag.com/api/v1/searches/<search_id>/
Response description
See Search object
Perform a search
You can download the registered tour-eiffel.jpeg file from the media example to run the example.
import requests
headers = {
"Authorization": "Token <your api token>",
"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 <your api token>" \
-F "file=@tour-eiffel.jpeg"
The above commands returns JSON structured like this:
{
"status": "complete",
"matches": [
{
"created": "2019-11-18T16:29:20.483229Z",
"type": "user",
"watermarked": true,
"image": {
"type": "registered",
"url": "https://static1.imatag.com/54578,15ec5ca69f80719a",
"width": 1280,
"height": 1706,
"thumbnail": "https://static4.imatag.com/211701,81c386bd3eb68eba",
"credit": null
},
"paths": [
{
"url": "https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg",
"path": "api.demo/images/paris/tour-eiffel.jpeg",
"created": "2018-07-20T15:15:49.548216Z",
"disk_usage": 497153,
"type": "image",
"thumbnail": "https://static4.imatag.com/211701,81c386bd3eb68eba",
"image": "https://static4.imatag.com/54578,15ec5ca69f80719a",
"web_matches": "https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg/_matches/web/",
"press_matches": "https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg/_matches/press/",
}
]
}
]
}
alternatively you can perform a request by url
import requests
headers = {
"Authorization": "Token <your api token>",
"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 <your api token>" \
-F "url=https://imatag.com/api/doc/images/tour-eiffel.jpeg"
The above commands returns JSON structured like this:
{
"status": "complete",
"matches": [
{
"created": "2019-11-18T16:36:35.588984Z",
"type": "user",
"watermarked": true,
"image": {
"type": "registered",
"url": "https://static1.imatag.com/54578,15ec5ca69f80719a",
"width": 1280,
"height": 1706,
"thumbnail": "https://static3.imatag.com/211701,81c386bd3eb68eba",
"credit": null
},
"paths": [
{
"url": "https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg",
"path": "api.demo/images/paris/tour-eiffel.jpeg",
"created": "2018-07-20T15:15:49.548216Z",
"disk_usage": 497153,
"type": "image",
"thumbnail": "https://static3.imatag.com/211701,81c386bd3eb68eba",
"image": "https://static1.imatag.com/54578,15ec5ca69f80719a",
"web_matches": "https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg/_matches/web/",
"press_matches": "https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg/_matches/press/",
}
]
}
]
}
You can also perform an asynchronous search:
import requests
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "image/jpeg",
}
files = {'file': open('tour-eiffel.jpeg', 'rb'), 'sync': 0}
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 <your api token>" \
-F "file=@tour-eiffel.jpeg" \
-F "sync=0"
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"
}
You can then GET the search at the returned url field.
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
POST
https://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) |
similar | If set, disable geometry validation and watermark check; faster search; default is false | |
transform | "scale" | geometry validation model for images; default is scale (crop/resize no rotation), other allowed values are affine (crop/resize/rotation) or perspective |
Response description
If the request is successful, the response is a Search object. HTTP status code is 201 for asynchronous requests and 200 for synchronous requests.
Delete an existing search
import requests
headers = {
"Authorization": "Token <your api token>",
}
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 <your api token>"
This endpoint deletes an existing search and associated matches.
HTTP Request
DELETE
https://imatag.com/api/v1/searches/<search_id>/
Watermarking
The watermarking endpoint allows you to apply an invisible watermark on a file. The watermarked file can then be:
- downloaded for distribution to your customers, ...
- registered as a media so that its usage can be tracked on the Internet, by our crawlers. See the Media endpoint
Watermarking a file
Watermarking by URL
import requests
headers = {
"Authorization": "Token <your api token>",
}
data = {
"url": "https://imatag.com/api/doc/images/tour-eiffel.jpeg",
"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 <your api token>" \
-H "Content-Type: application/json" \
--data '{"url": "https://imatag.com/api/doc/images/tour-eiffel.jpeg", "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",
"registration": "http://static4.imatag.com/208145,240d163d6fdc2249"
}
HTTP Request
POST
https://imatag.com/api/v1/watermarking/
Request content
The content of the request must be either:
- the full binary content of the image file. The Content-Type header must be set according to the image format.
- JSON data
- the URL of the asset
"url": "http://..."
- the sync call of the api
"sync": true
(true or false, default = true) - the timeout call of the api
"timeout": 120
(0 <= integer <= 120, default = 120)
- the URL of the asset
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:
X-RateLimit-Watermarking-Daily
: the maximum number of watermarkingX-RateLimit-Watermarking-Daily-Remaining
: the remaining count of watermarking still available
Watermark an image
Watermarking image by direct upload
import requests
headers = {
"Authorization": "Token <your api token>",
"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 <your api token>" \
-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
{
"expiry": "2018-12-06T17:26:22Z",
"original": "http://static1.imatag.com/208141,240d162ab9716c41",
"watermarked": "http://static2.imatag.com/208141,240d164028af21c7",
"registration": "http://static4.imatag.com/208145,240d163d6fdc2249"
}
Image have an additional return:
Attribute | Description |
---|---|
registration | The URL of the registration data that should be sent on the media endpoint |
Detect a watermarked image
Watermark detection
import requests
headers = {
"Authorization": "Token <your api token>",
}
data = {
"query": "http://static2.imatag.com/208141,240d164028af21c7",
"registration": "http://static4.imatag.com/208145,240d163d6fdc2249"
#or "registration": "https://imatag.com/api/v1/media/api.demo/images/paris/tour-eiffel.jpeg"
}
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 <your api token>" \
-H "Content-Type: application/json" \
--data '{"query": "https://imatag.com/api/doc/images/query.jpeg", "registration": "http://static4.imatag.com/208145,240d163d6fdc2249"}'
The above command returns JSON structured like this:
{
"marked": true
}
HTTP Request
POST
https://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).
This is for when you want to do exactly one detection, know exactly which watermark you want to detect and expect a boolean answer. If you want to find out which watermark, if any, is present in the image (either because you have several watermarked versions of the same image or because you are not sure what was the original image), you should use the searches endpoint instead.
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) |
registration | false | The URL of the registration file (containing the watermark data) for comparison against the query. Data URIs are supported as well as urls of registered images in media. |
original | false | The URL of the original image matching the transactional registration file. Data URIs are supported. |
secret | false | The secret passphrase used during the watermarking process if applicable. |
payload_max | false | Maximum value of the payload integer (0-16777215) if applicable. |
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. |
Get the encryption key
Get the encryption key
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get(
"https://imatag.com/api/v1/watermarking/key/",
headers=headers)
curl https://imatag.com/api/v1/watermarking/key/
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"key": "-----BEGIN RSA PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DIDAQAB\n-----END RSA PUBLIC KEY-----"
}
HTTP Request
GET
https://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.
- Download the "Software" version corresponding to your server(s) operating system (Linux or Windows).
It will be saved to
lamark
(Linux) orlamark.exe
(Windows) - Download your "Encryption key". It will be saved to
public_key.der
.
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:
- the software has
executable
rights. This probably won't be the case just after downloading the software. - it has read access to the encryption key and the input images
- it has write access to the folder(s) where you will be writing the output images and the registration files.
Software usage
Assuming your current directory contains
lamark
,public_key.der
andinput_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
andregistration.lmk
in your current directory.
lamark [options] <input_image.jpg> <output_image.jpg> <registration.lmk> <public_key.der>
Parameters | Description |
---|---|
<input_image.jpg> | The full-resolution input image, in JPEG format |
<output_image.jpg> | The full-resolution output watermarked 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
- If the watermarking was successful, it doesn't output anything else and return an exit code 0
- If the parameters were invalid, the software will output the usage on
stderr
and return an exit code 1 - If any other error occurred, the software will output details on
stderr
and return an exit code 2
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 its 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 <your api token>",
"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 <your api token>" \
-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
POST
https://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 <your api token>",
}
response = requests.get(
"https://imatag.com/api/v1/account/",
headers=headers)
curl -X GET \
https://imatag.com/api/v1/account/ \
-H "Authorization: Token <your api token>"
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,
"home": "api-demo",
}
HTTP Request
GET
https://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 |
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 |
home | the home directory of the user |
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": "<your api token>",
}
This endpoint (generates and) returns an API key, that shall be used for any other API call, for a user with valid IMATAG credentials.
HTTP Request
POST
https://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 extension (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 blacklist
Add a domain to the blacklist:
import requests
headers = {
"Authorization": "Token <your api token>",
}
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 <your api token>" \
-H "Content-Type: application/json" \
--data '{"url": "imatag.com"}'
This endpoint allows to add a domain to the blacklist
HTTP Request
POST
https://imatag.com/api/v1/domains/blacklist/
Get the domain blacklist
Get the domain blacklist:
import requests
headers = {
"Authorization": "Token <your api token>",
}
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 <your api token>"
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
GET
https://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 <your api token>",
'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 <your api token>" \
-H "Content-Type: application/json" \
--data '{"url": "imatag.com"}'
This endpoint allows to removes a domain from the backlist
HTTP Request
DELETE
https://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 <your api token>"
# 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:
- upload the image to imatag,
- watermark the image via its URL,
- register the watermarked image in the account.
Versioning
The versioning of the API is specified as part of the URI.
For instance, in order to use v3 of the API the request URI should begin with /api/v3
followed by a specific endpoint.
https://imatag.com/api/v3/<endpoint>
Supported versions are:
API Version | Documentation link |
---|---|
v1 (deprecated) | v1 |
v2 (stable) | v2 |
v3 (stable) | v3 |