Quick Start
Welcome to the Imatag documentation ! This page will give you an introduction to 80% of the Imatag platform, enabling you to seamlessly integrate our API and efficiently watermark your files.
You will discover:
- How to authenticate with our system
- How to watermark a file
- How to register a watermarked file
- How to search a watermarked file
Authentication - OAuth2
OAuth 2.0 is an authorization protocol that allows an application (client) to access a user's resources hosted on a server without sharing their login credentials. It operates by granting access tokens that provide precise control over permissions and the duration of access.
How it works ?
Understanding OAuth 2.0: A Step-by-Step Diagram:
Why use OAuth2 ?
Advantage | Description |
---|---|
Granular access control | If a client has multiple applications with different purposes, you can grant or revoke access per app individually without affecting the others. |
Temporary access for third parties | You can give a contractor or external partner limited-time access, and easily revoke it once they’re no longer involved. |
Better security than permanent tokens | OAuth2 uses short-lived access tokens and refresh tokens, reducing the risk in case a token is compromised. |
How to use OAuth2 ?
Now that we have a solid understanding of OAuth2 and its advantages, let's dive into the practical side and implement it step-by-step.
Step 1 : Obtain client information
Create an application to get your client_id
and client_secret
.
On the platform UI, go to Account Settings by clicking on the ⚙️ icon.
There, you’ll find a "Create OAuth Application" button.
Clicking it will generate your Client ID and Client Secret.
Step 2 : Obtain an Access Token
Use your client_id
and client_secret
to request a token
Get access token
import base64
import requests
client_id = "your_client_id"
client_secret = "your_client_secret"
credentials = f"{client_id}:{client_secret}"
encoded_credentials = base64.b64encode(credentials.encode("utf-8")).decode("utf-8")
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": f"Basic {encoded_credentials}"
}
url = "https://imatag.com/o/token/"
response = requests.post(url, headers=headers, params={"grant_type": "client_credentials"})
curl -X POST "https://imatag.com/o/token/" \
-H "Authorization: Basic your_encoded_credentials" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials"
You'll get a response like this :
{
"access_token": "your_token",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "openid"
}
To get a token you need to encode client_id
and client_secret
separated by a colon as HTTP base authentication encoded in base64
.
HTTP Request
POST
https://imatag.com/o/token/
Request content
- The content-type of the request must be
application/x-www-form-urlencoded
.
Attribute | Required | Value |
---|---|---|
grant_type | True | client_credentials |
Response description
Attribute | Description |
---|---|
access_token | Your access token |
expires_in | Time of validity in seconds |
token_type | The type of token |
scope | The scope of the access token |
Step 3: Use the token to access resources
The access token should be used as follows:
import requests
headers = {"Authorization": "Bearer your_access_token"}
response = requests.get("https://imatag.com/api/v4/account/", headers=headers)
curl "https://imatag.com/api/v4/account/" \
-H "Authorization: Bearer your_access_token"
The above command returns a JSON response with various details about your account.
For now, here’s a glimpse of the most relevant part
{
...
"home": "api-demo",
...
}
Now that you have your access_token
, you need to use it as your credential. To do so, simply use it as a Bearer token.
For example, you can retrieve your user home directory. it's helpful you may use it after, so good to know.
to view more details about your account check your account details here.
HTTP Request
GET
https://imatag.com/api/v4/account/
Response description
Attribute | Description |
---|---|
home | The home directory of the user |
Watermarking Workflow
After completing the authentication step through OAuth 2.0, you can easily watermark your files by following the process outlined below. This step-by-step guide will help you apply this functionality efficiently.
Watermarking a file
Watermarking an image 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/v4/watermarking/",
json=data, headers=headers)
curl -X POST \
https://imatag.com/api/v4/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/v4/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.
- A JSON data with the following attributes:
Attribute | Required | Description |
---|---|---|
url | true | The URL of the asset "http://..."` |
sync | false | The sync call of the api (true or false, default = true) |
timeout | false | The timeout call of the api |
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) |
registration | The URL of the registration data that should be sent on the media endpoint |
Register a watermarked file
HTTP Request
This endpoint registers a previously watermarked file using the registration (LMK) file generated by the previous endpoint watermarking endpoint. It also allows to add metadata to the media.
First example with the lmk file
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/v4/media/api.demo/uploads/2018/my-image.jpg",
data=lmk, headers=headers)
curl -X PUT \
https://imatag.com/api/v4/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:
{
"url": "https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg",
"path": "api.demo/uploads/2018/my-image.jpg",
"created": "2019-01-02T15:09:17.145580Z",
"disk_usage": 97358,
"type": "image",
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad",
"metadata": {},
"image": {
"type": "registered",
"url": "https://static4.imatag.com/20985,28c25e65d3e1baad",
"width": 800,
"height": 500,
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad"
}
}
Second example with the JSON file
import requests
import json
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "application/json",
}
data = {
"url": "https://static3.imatag.com/49785,25dcc2978a4b5bad",
"metadata": {
"user.isDemo": "True",
"user.campaign": "Visit Paris 2020"
}
}
response = requests.put("https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg",
data=json.dumps(data), headers=headers)
curl -X PUT \
https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg \
-H "Authorization: Token <your api token>" \
-H "Content-Type: application/json" \
-d '{"url": "https://static3.imatag.com/49785,25dcc2978a4b5bad", "metadata": { "user.isDemo": "True", "user.campaign": "Visit Paris 2020"}}'
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg",
"path": "api.demo/uploads/2018/my-image.jpg",
"created": "2019-01-02T15:09:17.145580Z",
"disk_usage": 97358,
"type": "image",
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad",
"metadata": {
"user.isDemo": "True",
"user.campaign": "Visit Paris 2020"
},
"image": {
"type": "registered",
"url": "https://static4.imatag.com/20985,28c25e65d3e1baad",
"width": 800,
"height": 500,
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad"
}
}
An additional example data-URI example is given in the Uploads section
PUT
https://imatag.com/api/v4/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 endpoint. The content-type of the request must be
application/lmk
. - A JSON with the following attributes. The content-type of the request must be
application/json
.
Attribute | Required | Description |
---|---|---|
url | true | URL of the lmk file, for example the one provided by the watermarking endpoint. |
metadata | false | A metadata object |
Response description
If the request is successful, the response is the newly created Media object
Search a watermarked file
Now that our file has been watermarked and registered, we can perform a search on it.
Search with a binary file, by direct upload. (See example)
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>"
}
files = {'file': open('tour-eiffel.jpeg', 'rb')}
response = requests.post("https://imatag.com/api/v4/searches/",
files=files, headers=headers)
curl -X POST \
https://imatag.com/api/v4/searches/ \
-H "Authorization: Token <your api token>" \
-F "file=@tour-eiffel.jpeg"
The above commands returns JSON structured like this:
{
"status": "complete",
"matches": [
{
"id": null,
"created": "2019-11-18T16:40:11.133727Z",
"type": "user",
"watermarked": true,
"image": {
"type": "registered",
"url": "https://static4.imatag.com/54578,15ec5ca69f80719a",
"width": 1280,
"height": 1706,
"thumbnail": "https://static4.imatag.com/211701,81c386bd3eb68eba",
"credit": null,
"media_path": "/api.demo/images/paris/tour-eiffel.jpeg",
"media_url": "https://imatag.com/api/v4/media/api.demo/images/paris/tour-eiffel.jpeg"
}
}
]
}
Search with a remote image, by providing its public URL. (See example)
alternatively you can perform a request by url
import requests
import json
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "application/json",
}
data = {'file': 'https://imatag.com/api/doc/images/tour-eiffel.jpeg'}
response = requests.post("https://imatag.com/api/v4/searches/",
data=json.dumps(data), headers=headers)
curl -X POST \
https://imatag.com/api/v4/searches/ \
-H "Authorization: Token <your api token>" \
-F "file=https://imatag.com/api/doc/images/tour-eiffel.jpeg"
The above commands returns JSON structured like this:
{
"status": "complete",
"matches": [
{
"id": null,
"created": "2019-11-18T16:39:02.263262Z",
"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,
"media_path": "/api.demo/images/paris/tour-eiffel.jpeg",
"media_url": "https://imatag.com/api/v4/media/api.demo/images/paris/tour-eiffel.jpeg"
}
}
]
}
You can perform a text search
import requests
import json
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "application/json",
}
data = {
"metadata": {
"user.subject": "Eiffel Tower"
},
"filename" : "tour-eiffel.jpeg",
"type": "image"
}
response = requests.post("https://imatag.com/api/v4/searches/",
data=json.dumps(data), headers=headers)
The above commands returns JSON structured like this:
{
"status": "complete",
"matches": [
{
"id": null,
"created": "2020-10-23T13:41:21.743541Z",
"type": "text",
"query": {
"filename": "tour-eiffel.jpeg",
"type": [
"image"
],
"sync": true,
"metadata": {
"user.subject": "Eiffel Tower"
}
},
"media": {
"metadata": {
"user.subject": "Eiffel Tower",
"user.campaign": "Paris by night"
},
"media_path": "api.demo/images/paris/tour-eiffel.jpeg",
"media_url": "https://imatag.com/api/v4/media/api.demo/images/paris/tour-eiffel.jpeg"
}
}
]
}
HTTP Request
POST
https://imatag.com/api/v4/searches/
Request content
For a search by image, the following parameters are available
Parameter | Default | Description |
---|---|---|
file | null | Query file (image or document) if the request is multipart/form-data, or the URL of the query image or document (Data URIs are supported) |
name | null | If set, name for the search. If unset, the filename of the uploaded "file" 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 | |
search_path | <homedir> |
Restrict the search to a specific media path (<homedir>/<path> ). Ignored for category web . |
mode | "near_duplicate" | Can be near_duplicate to attempt to find the original image(s) the query is derived from or vice-versa, if the matched original is watermarked, detection will be performed. Alternatively can be set to similar to do a faster search in order to find visually similar images which are not necessarily derived from one another or 'leaks'. |
categories | ["default"] | A list to where to search; for image search only; authorized users only. The default may be changed to one of recent (recent images, faster), archive (all images, slower). |
transforms | ["scale"] | Geometric transform validation model for images; default is scale (crop/resize no rotation), other allowed values are affine (crop/resize/rotation) or perspective . If mode=leaks , default is ["scale", "perspective"] . |
filter_marked | false | If set, filter the results to only show watermarked results (true) or non-watermarked (false) |
For a search by text, the following parameters are available
Parameter | Default | Description |
---|---|---|
metadata | null | Dict that represent metadata to search |
type | null | String to search only specific media type ("image", "video", "folder") |
filename | null | String that represent the exact filename to search (case sensitive) |
filename__startswith | null | String that represent the begining of the filename to search (case sensitive). Minimum length required = 3 |
sync | true | Run the search in synchronous mode if set |
Response content
The response is one of the following, depending on the sync query parameter:
- For a synchronous search, the response is a Search object with 200 as status code
- For anasynchronous search, the response is a 201 status code (to be checked afterwards)
API Endpoints
Below is the list of all available endpoints & their full description: this is API (ツ) time!
Account
Account information
This endpoint allows you to check your account information and status.
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get(
"https://imatag.com/api/v4/account/",
headers=headers)
curl -X GET \
https://imatag.com/api/v4/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",
"incidents": null,
"image_count": 9,
"image_quota": 50,
"disk_quota": 13030726,
"disk_usage": 2544966,
"home": "api-demo",
"permissions":[],
"quotas": {
"uploaded_marks": 7,
"uploaded_marks_limit": 50,
"uploaded_images": 9,
"uploaded_images_limit": 100,
"active_paths_in_home": 12,
"active_paths_in_home_limit": null,
"paths_in_home": 12,
"paths_in_home_limit": null,
"user_paths": 12,
"user_paths_limit": null
}
}
HTTP Request
GET
https://imatag.com/api/v4/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 | |
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 (null if no maximum) |
disk_usage | Current disk usage of the user (in bytes) |
disk_quota | Maximum disk usage (null if no maximum) |
expires | Only in case of certain incidents, the date at which the account will be deleted |
home | The home directory of the user |
quota | Detailed quota |
permissions | List of allowed permissions for the current account |
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 last payment of the user 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 |
Account settings
This endpoint allows you to check your account settings.
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get(
"https://imatag.com/api/v4/account/settings/",
headers=headers)
curl -X GET \
https://imatag.com/api/v4/account/settings/ \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"lang": "en",
"notifications": {
"notify_upload": true,
"notify_pdf": false,
"notify_web": false,
"notify_download": false,
"notify_favorite": false,
"notify_newsletter": true,
"notify_offers": false,
"notify_pdf_daily": false,
"notify_pdf_weekly": false,
"notify_match_url_daily": false,
"notify_match_url_weekly": false,
"notify_match_site_daily": false,
"notify_match_site_weekly": false
},
"notif_site_countries": [
"fr"
]
}
HTTP Request
GET|POST
https://imatag.com/api/v4/account/settings/
Response description
Attribute | Description |
---|---|
lang | Language (fr, en) |
notifications | Dictionary of key:value |
notif_site_countries | List of countries for which the website matches notifications will be sent. Countries must be specified as ISO 3166-1 alpha-2 codes (ie 2-letter codes; cf https://fr.wikipedia.org/wiki/ISO_3166-1_alpha-2) |
Download software and key
There is an endpoint that allows you to list the latest software version's binaries available.
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get(
"https://imatag.com/api/v4/account/download/",
headers=headers)
curl -X GET \
https://imatag.com/api/v4/account/download/ \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"version": "X.Y.Z",
"key": {
"public_key.der": "/api/v4/account/download/key/"
},
"software": {
"lamark": "/api/v4/account/download/software/X.Y.Z/lamark",
"lamark.exe": "/api/v4/account/download/software/X.Y.Z/lamark.exe"
}
}
HTTP Request
GET
https://imatag.com/api/v4/account/download/
Response description
Attribute | Description |
---|---|
version | The name of the current version |
key | A dict of each key you can have |
key.<name> |
The url to call (GET) to get your encryption key |
software | A dict where each key represent a software available |
software.<name> |
The url to call (GET) to download this specific software |
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. |
Domains blacklist
This endpoint /api/v4/domains/blacklist/
allows to manage a blacklist of web 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/v4/domains/blacklist/",
json=data, headers=headers)
curl -X POST \
https://imatag.com/api/v4/domains/blacklist/ \
-H "Authorization: Token <your api token>" \
-H "Content-Type: application/json" \
--data '{"url": "imatag.com"}'
This endpoint allows to add a new domain to the blacklist
HTTP Request
POST
https://imatag.com/api/v4/domains/blacklist/
Request content
The content of the request must be a valid domain description:
Attribute | Required | Description |
---|---|---|
url | true | Domain name with extension |
Response description
If the request is successful, the response is the newly blacklisted domain
Get all domains from the blacklist
Get all domains from the blacklist:
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get(
"https://imatag.com/api/v4/domains/blacklist/",
headers=headers)
curl -X GET \
https://imatag.com/api/v4/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 registered in the blacklist
HTTP Request
GET
https://imatag.com/api/v4/domains/blacklist/
Response description
Attribute | Description |
---|---|
next | Not used yet; pagination is not enabled on this endpoint |
previous | Not used yet; pagination is not enabled on this endpoint |
results | List of blacklisted domain objects |
Removes a domain from the blacklist
Removes a domain from the blacklist:
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/v4/domains/blacklist/",
data=json.dumps(data), headers=headers)
curl -X DELETE \
https://imatag.com/api/v4/domains/blacklist/ \
-H "Authorization: Token <your api token>" \
-H "Content-Type: application/json" \
--data '{"url": "imatag.com"}'
This endpoint allows to remove a domain from the blacklist
HTTP Request
DELETE
https://imatag.com/api/v4/domains/blacklist/
Request content
The content of the request must be a valid domain description:
Attribute | Required | Description |
---|---|---|
url | true | Domain name with extension |
Matches
This endpoint lists all web matches found (similar and watermarked) on the Internet by our crawlers.
Get all web matches
Use this endpoint to retrieve the list of web matches.
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v4/matches/", headers=headers)
curl 'https://imatag.com/api/v4/matches/' \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"count": 1126515812,
"next": "https://internal.imatag.com/api/v4/matches/?cursor=cD0xNzQzNjg0NTg5OTc2JmM9MTEyNjUxNTgxMg%3D%3D",
"previous": null,
"results": [
{
"id": "-1309647177151738849",
"date_created": "2025-04-03T12:49:55.313776Z",
"date_updated": "2025-04-03T12:49:55.313776Z",
"export": true,
"watermarked": false,
"tags": [],
"sessions": [
5
],
"media": {
"id": -5249833301997058969,
"type": "image",
"thumbnail": "https://static6.imatag.com/304162,01e32371b0c3de16d9",
"image": "https://static6.imatag.com/304162,01e32371b0c3de16d9",
"path": "maxppp/agencesonline/11718303.jpg.jpg",
"date_registered": "2024-11-13T13:56:44.375258Z",
"credit": "EPA/MAXPPP",
"user_metadata": {
"reference": "11718303"
}
},
"site": {
"id": -315702766390685278,
"name": "fbcnews.com.fj",
"domain": "fbcnews",
"suffix": "com.fj",
"country": "fj"
},
"page": {
"url": "https://www.fbcnews.com.fj/entertainment/vicky-kaushal-starrer-the-great-indian-family-certified-ua-advance-booking-begins/",
"type": "web",
"image": {
"url": "https://www.fbcnews.com.fj/wp-content/uploads/2024/11/world-8-640x360.jpg"
}
}
},
...
]
}
HTTP Request
GET
https://imatag.com/api/v4/matches/
What's in a Match?
Each match object contains metadata grouped in three sections:
media
: Information about the matched imagesite
: Where the image was foundpage
: Contextual info about the page hosting the image
Match Fields Breakdown
Field | Description |
---|---|
watermarked |
Whether watermark was detected (true /false ) |
sessions |
Related crawling session ID(s) |
tags |
Optional tags you’ve applied |
export |
Whether the result is exportable |
date_created |
Date of match creation |
payload |
Payload used for the watermark (payload mode only) |
Nested objects:
- media: Contains details about the client’s image which generated the match.
Field | Description |
---|---|
id |
Unique media id |
type |
Type of media: image, video, or other |
thumbnail |
URL of the thumbnail preview of the media |
image |
URL of the original image |
path |
File path or location where the media is stored |
date_registered |
Date of registration |
user_metadata.reference |
Metadata pushed to the path |
- site: Contains information about the website where the image was found.
Field | Description |
---|---|
domain |
Main domain of the website (e.g., example.com) |
name |
Name of the website |
country |
Country of the site where the image was detected |
- page: Contains information about the website where the image was found.
Field | Description |
---|---|
url |
Url of the page containing the image |
type |
Type of page (e.g., article, web) |
headline |
Main headline or title of the page |
description |
Brief summary or meta description of the page |
author |
Name of the author or publisher of the page |
date_modified |
Date when the page was last updated (available only for article pages) |
date_published |
Publication date of the page (available only for article pages) |
Filtering Matches
Here's an example of how to filter matches
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v4/matches/?watermarked=true&date_created__gte=2025-06-26T07:03:17.550062Z", headers=headers)
curl 'https://imatag.com/api/v4/matches/?watermarked=true&date_created__gte=2025-06-26T07:03:17.550062Z' \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
"next": "https://imatag.com/api/v4/matches/?cursor=cD0xNzUwOTIxNDI3MTg5JmM9MTgz&date_created__gte=2025-06-26T07%3A03%3A17.550062Z&watermarked=true",
"previous": null,
"results":
{
"id": "-5838135365226425586",
"date_created": "2025-06-26T07:04:09.139659Z",
"date_updated": "2025-06-26T07:04:09.143115Z",
"export": true,
"watermarked": true,
"tags": [],
"sessions": [
7211
],
"media": {
"id": 8367688270167670191,
"type": "image",
"thumbnail": "https://static30.imatag.com/310396,01f3bed1574b1b8181",
"image": "https://static30.imatag.com/310396,01f3bed1574b1b8181",
"path": "AFP_36N88JP",
"date_registered": "2025-05-12T07:19:44.594685Z",
"credit": "AFP",
"user_metadata": {
"reference": "AFP_36N88JP"
}
},
"site": {
"id": -484839104856309443,
"name": "wionews.com",
"domain": "wionews",
"suffix": "com",
"country": "in"
},
"page": {
"url": "https://www.wionews.com/tags/devdutt-padikkal",
"type": "web",
"image": {
"url": "https://cdn1.wionews.com/dev/wion/images/2025/20250505/virat-kohli-test-gallery-5-623434.png?im=FitAndFill=(700,400)?im=FitAndFill=(910,512)"
}
}
}
You can filter matches using query parameters.
Examples:
- Only non-watermarked results:
HTTP Request
GET
https://imatag.com/api/v4/matches/?watermarked=true
- Filter by a specific domain:
HTTP Request
GET
https://imatag.com/api/v4/matches/?site.domain=example.com
- Combine filters:
HTTP Request
GET
https://imatag.com/api/v4/matches/?watermarked=true&media.id=123456
Available Filters
Parameter | Description |
---|---|
id |
The unique id of the match |
date_created / __gte / __lte / __gt / __lt |
Date filters |
watermarked |
Filter by watermark presence |
site.id |
Match a specific site |
site.name |
Filter results by the name of the site |
site.suffix |
Filter matches by the domain suffix (e.g., .com, .fr) |
media.id |
Match a specific media |
media.path |
Filter results by the path of the media |
blacklist |
Exclude blacklisted domains |
export |
If true, this match is eligible for CSV export |
tags |
Custom tags that can be attached to the match for categorization or filtering |
sessions |
If set, only results originating from these Crawling Session ids will be shown (supports one or multiple IDs). |
page.url |
Url of the page containing the image |
page.date_published |
Publication date of the page (available only for article pages) |
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 obvious 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't use "." at the first letter of the folder or media names as it is reserved for internal usage.
- 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.
Models
The generic media model is composed of a list of common properties, listed below, and specific sub properties
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 , video , document |
children | For folder , the list of objects contained in that folder (paginated) |
metadata | For any type of object, the list of the associated metadata. |
image | If it exists, details the Image object. |
video | If it exists, details the Video object. |
exclusive | For image , indicates whether an image is exclusive or not. If not specified, exclusivity is unknown. |
Metadata Object
Example of a metadata object:
{
"user.campaign": "my new campaign",
"user.hasBeenValidated": true,
"user.credited": null, # This field is not saved on media registration, but is deleted on media update
"customer": "another customer" # This field is not valid
}
metadata is a dictionary containing fields composed of keys and values:
- Keys are strings that are prefixed.
- "user." can be used for any custom field. ex: "user.campaign" is a valid key, "campaign.name" isn't.
- Values are either strings up to 255 characters, booleans (True or False), or null. This last value is ignored when registering a new media, and is used to delete a field when updating the metadata object.
Image Object
Attribute | Description |
---|---|
url | URL of the actual image file |
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 |
format | Format of the image (e.g. jpeg or png ) |
thumbnail | URL of the image thumbnail, null if unavailable |
credit | Credit line of this image, null if empty |
Additionally, depending on the type
, images have extra fields:
Type registered
:
Attribute | Description |
---|---|
media_path | Path of the Media object where the image is registered |
media_url | URL of the Media object where the image is registered |
Type web
:
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) |
Video Object
Attribute | Description |
---|---|
url | URL of the actual video file (not always available) |
type | Type of video, set to registered or watermarked respectively for non-watermarked or watermarked videos registered via the Media API |
width | Width of the video in pixels |
height | Height of the video in pixels |
thumbnail | Url of the video thumbnail |
duration | Duration of the video |
format | Format of the video, among the followings: mov , mp4 , m4a , 3gp , 3g2 , mj2 |
Additionally, depending on the type
, images have extra fields:
Type registered
:
Attribute | Description |
---|---|
streaming_url | URL of a video file optimized for streaming (if available) |
Type watermarked
:
Attribute | Description |
---|---|
secret | Secret used for the watermark |
max_payload | Max_payload used for the watermark (payload mode only) |
payload | Payload used for the watermark (payload mode only) |
original_path | Path of the Media object where the original video is registered (if available) |
original_url | URL of the original video file |
List a folder
import requests
headers = {
'Authorization': 'Token <your api token>',
}
response = requests.get('https://imatag.com/api/v4/media/api.demo/images', headers=headers)
curl https://imatag.com/api/v4/media/api.demo/images \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v4/media/api.demo/images",
"path": "api.demo/images",
"created": "2018-07-20T15:04:33.221902Z",
"disk_usage": 242602,
"type": "folder",
"thumbnail": null,
"metadata": {},
"children_count": 2,
"subfolders_count": 2,
"media_count": 0,
"next": null,
"previous": null,
"children": [
{
"url": "https://imatag.com/api/v4/media/api.demo/images/paris",
"path": "api.demo/images/paris",
"created": "2018-07-20T15:13:06.259863Z",
"disk_usage": 0,
"type": "folder",
"thumbnail": null,
"metadata": {},
"children_count": 1,
"subfolders_count": 0,
"media_count": 2
},
{
"url": "https://imatag.com/api/v4/media/api.demo/images/new-york",
"path": "api.demo/images/new-york",
"created": "2018-07-20T15:16:07.777535Z",
"disk_usage": 0,
"type": "folder",
"thumbnail": null,
"metadata": {},
"children_count": 1,
"subfolders_count": 0,
"media_count": 4
}
]
}
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/v4/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. |
Query Parameters
Parameter | Default | Description |
---|---|---|
hidden | 0 | Show hidden folders & media (name starting with '.') |
Response description
See Media object
Get a media
import requests
headers = {
'Authorization': 'Token <your api token>',
}
response = requests.get('https://imatag.com/api/v4/media/api.demo/images/paris/tour-eiffel.jpeg',
headers=headers)
curl https://imatag.com/api/v4/media/api.demo/images/paris/tour-eiffel.jpeg \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v4/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": 97358,
"type": "image",
"thumbnail": "https://static1.imatag.com/54578,15ec5ca69f80719a",
"metadata": {
"user.subject":"Eiffel Tower",
"user.campaign":"Paris by night"
},
"image": {
"type": "registered",
"url": "https://static1.imatag.com/59713,10a05da70fc4",
"width": 800,
"height": 500,
"thumbnail": "https://static1.imatag.com/54578,15ec5ca69f80719a",
"credit": "© 2012 Cameron Rutt"
}
}
This endpoint retrieves information about the media at a given path.
HTTP Request
GET
https://imatag.com/api/v4/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
This endpoint registers a previously watermarked media using the registration (LMK) file generated by the watermarking software or the API's watermarking endpoint. It also allows to add metadata to the media.
First example with the lmk file 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/v4/media/api.demo/uploads/2018/my-image.jpg",
data=lmk, headers=headers)
curl -X PUT \
https://imatag.com/api/v4/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:
{
"url": "https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg",
"path": "api.demo/uploads/2018/my-image.jpg",
"created": "2019-01-02T15:09:17.145580Z",
"disk_usage": 97358,
"type": "image",
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad",
"metadata": {},
"image": {
"type": "registered",
"url": "https://static4.imatag.com/20985,28c25e65d3e1baad",
"width": 800,
"height": 500,
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad"
}
}
Second example with the JSON file
import requests
import json
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "application/json",
}
data = {
"url": "https://static3.imatag.com/49785,25dcc2978a4b5bad",
"metadata": {
"user.isDemo": "True",
"user.campaign": "Visit Paris 2020"
}
}
response = requests.put("https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg",
data=json.dumps(data), headers=headers)
curl -X PUT \
https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg \
-H "Authorization: Token <your api token>" \
-H "Content-Type: application/json" \
-d '{"url": "https://static3.imatag.com/49785,25dcc2978a4b5bad", "metadata": { "user.isDemo": "True", "user.campaign": "Visit Paris 2020"}}'
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg",
"path": "api.demo/uploads/2018/my-image.jpg",
"created": "2019-01-02T15:09:17.145580Z",
"disk_usage": 97358,
"type": "image",
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad",
"metadata": {
"user.isDemo": "True",
"user.campaign": "Visit Paris 2020"
},
"image": {
"type": "registered",
"url": "https://static4.imatag.com/20985,28c25e65d3e1baad",
"width": 800,
"height": 500,
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad"
}
}
An additional example data-URI example is given in the Uploads section
PUT
https://imatag.com/api/v4/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
. - A JSON with the following attributes. The content-type of the request must be
application/json
.
Attribute | Required | Description |
---|---|---|
url | true | URL of the lmk file, for example the one provided by the watermarking endpoint. A data URI can also be used to upload a local LMK file (an example is given in the Uploads section). |
metadata | false | A metadata object |
Response description
If the request is successful, the response is the newly created Media object
Modify a media metadata
This example is based on the previous example
import requests
import json
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "application/json",
}
data = '''{
"metadata": {
"user.isDemo": null,
"user.campaign": "Visit Ulaanbaatar 2020"
}
}'''
response = requests.patch("https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg",
data=json.dumps(data), headers=headers)
curl -X PATCH \
https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg \
-H "Authorization: Token <your api token>" \
-H "Content-Type: application/json" \
-d '{"metadata": { "user.isDemo": null, "user.campaign": "Visit Ulaanbaatar 2020"}}'
The above command returns JSON structured like this:
{}
This endpoint can be used to update metadata after the media creation.
HTTP Request
PATCH
https://imatag.com/api/v4/media/<homedir>/<path>/<filename>
URL Parameters
Parameter | Required | Description |
---|---|---|
homedir | true | The home directory that contains 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 the media is stored (e.g. images/2018) |
filename | true | The file name & extension of the image. |
Request content
- The content-type of the request must be
application/json
. - The content of the request must be a JSON with the following attributes:
Attribute | Required | Description |
---|---|---|
metadata | false | A metadata object |
Response description
If the request is successful, a status code 200 is returned, along with an empty JSON.
Register a 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/v4/media/api.demo/uploads/2018/my-image.jpg",
data=image, headers=headers)
curl -X PUT \
https://imatag.com/api/v4/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/v4/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:
{
"url": "https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg",
"path": "api.demo/uploads/2018/my-image.jpg",
"created": "2019-01-02T15:09:17.145580Z",
"disk_usage": 97358,
"type": "image",
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad",
"metadata": {},
"image": {
"type": "registered",
"url": "https://static4.imatag.com/20985,28c25e65d3e1baad",
"width": 800,
"height": 500,
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad"
}
}
This endpoint allows to register a 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 or video, 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:
The exception to this is when you register a non-watermarked original video for subsequent watermarked video registration.
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
.
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 |
zip | application/zip | Binary file |
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/v4/media/api.demo/uploads/2018/my-image.jpg",
data=image, headers=headers)
curl -X PUT \
https://imatag.com/api/v4/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
Register a watermarked video
This example is for a watermarked video with payload
import requests
import json
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "application/json",
}
data = {
"type": "video",
"url": "https://imatag.com/api/v4/media/api.demo/uploads/original_video.mp4",
"secret": "my secret video",
"payload": 5,
"max_payload": 20,
}
response = requests.put("https://imatag.com/api/v4/media/api.demo/uploads/watermarked_video.mp4",
data=json.dumps(data), headers=headers)
curl -X PUT \
https://imatag.com/api/v4/media/api.demo/uploads/watermarked_video.mp4 \
-H "Authorization: Token <your api token>" \
-H "Content-Type: application/json" \
-d '{"type": "video", "url": "https://imatag.com/api/v4/media/api.demo/uploads/original_video.mp4",\
"secret": "my secret video", "payload": 5, "max_payload": 20}'
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v4/media/api.demo/uploads/watermarked_video.mp4",
"path": "api.demo/uploads/watermarked_video.mp4",
"created": "2019-01-02T15:09:17.145580Z",
"disk_usage": 31380,
"type": "video",
"thumbnail": "http://static4.imatag.com/71,02f024f4def5ac",
"metadata": {},
"video": {
"type": "watermarked",
"secret": "my secret video",
"max_payload": 20,
"payload": 5,
"url": null,
"width": 960,
"height": 540,
"duration": 18.234883,
"format": "mov,mp4,m4a,3gp,3g2,mj2",
"original_path": "api.demo/uploads/original_video.mp4",
"original_url": "http://static4.imatag.com/270,02f0231374f9b5",
"thumbnail": "http://static4.imatag.com/71,02f024f4def5ac"
}
}
There are no "registration file" for video like there are for images. As a consequence registering a watermarked video file requires manually sending several pieces of information including the original (un-watermarked) video file that must be provided as an url.
If you register a video watermarked without a payload, this url can point directly to a video file via a public url, or an url returned by the upload endpoint. It can also be the url of the media object for an already registered video (see Register non-watermarked file for similar tracking only).
If you register a video watermarked with a payload, this url must be that of the media object for an already registered video (see Register non-watermarked file for similar tracking only).
additional URL Parameters
Parameter | Required | Description |
---|---|---|
secret | true | Secret used for the watermark |
payload | false | Payload used for the watermark (integer), must be betweend 0 and max_payload |
max_payload | false | Max_payload used for the watermark (integer, required if payload is used, must be constant for a given secret and original video). |
Register multiple medias from a ZIP
This endpoint allows uploading multiple medias from a ZIP file into a folder at once. The ZIP file can contain mixed medias, such as images, videos or registration files.
import requests
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "application/zip",
}
lmk = open("./my-archive.zip", "rb").read()
response = requests.put("https://imatag.com/api/v4/media/api.demo/uploads/2018",
data=lmk, headers=headers)
curl -X PUT \
https://imatag.com/api/v4/media/api.demo/uploads/2018 \
-H "Authorization: Token <your api token>" \
-H "Content-Type: application/zip" \
--data-binary @- < ./my-archive.zip
HTTP Request
PUT
https://imatag.com/api/v4/media/<homedir>/<path>
URL Parameters
Parameter | Required | Description |
---|---|---|
homedir | true | The user home directory where the subfolder will be created (e.g. jdoe). |
path | true | The path of the subfolder to upload the zip to (e.g. images/2017). |
Delete an existing media
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.delete("https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg",
headers=headers)
curl -X DELETE \
https://imatag.com/api/v4/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/v4/media/<homedir>/<path>/<filename>
URL Parameters
Parameter | Required | Description |
---|---|---|
homedir | true | The home directory that contains 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/v4/media/api.demo/uploads/2018",
headers=headers,
)
curl -X PUT \
https://imatag.com/api/v4/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/v4/media/<homedir>/<path>
URL Parameters
Parameter | Required | Description |
---|---|---|
homedir | true | The user home directory where the subfolder will be created (e.g. jdoe). |
path | true | The path of the subfolder to create (e.g. images/2017). |
Delete an existing folder
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.delete("https://imatag.com/api/v4/media/api.demo/uploads/2018",
headers=headers)
curl -X DELETE \
https://imatag.com/api/v4/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/v4/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": "<homedir>/<path>",
"to" : "<homedir>/<other path>",
}
response = requests.post("https://imatag.com/api/v4/media/_move/",
json=data, headers=headers)
curl -L -X POST 'https://imatag.com/api/v4/media/_move/' \
-H 'Authorization: Token <your api token>' \
-H 'Content-Type: application/json' \
--data-raw '{
"url": "{{home}}/{{path}}",
"to": "{{home}}/{{new_path}}"
}'
The above command returns JSON structured like this:
{
"path": "<homedir>/<path>"
}
This endpoint moves a resource to another location
HTTP Request
POST
https://imatag.com/api/v4/media/_move/
Request content
Attribute | Required | Description |
---|---|---|
url | true | Path of the media to move or rename. |
to | true | New path of the media destination. The path will be created if needed. If to ends with a / , it will be considered as a folder where to move the media to. In any other cases, the original url will be moved/renamed to to . |
Response description
If the request is successful, the response contains the path of the moved/renamed resource.
Argument | Description |
---|---|
path | The new path of the media, once moved. |
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 synchronous searches, the search object contains the following fields:
Field | Description |
---|---|
status | The status of the search. Can be: complete or failed |
matches | When status is complete , the matches list is inlined |
For asynchronous searches, the search object contains the following fields:
Field | Description |
---|---|
status | The status of the search. Can be: complete , failed , pending , in progress , or cancelled , |
matches | When status is complete , the URL of the list of matches (see Match object) found in this search. |
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. |
Perform a search
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/v4/searches/
Request content
For a search by image, the following parameters are available
Parameter | Default | Description |
---|---|---|
file | null | Query file (image or document) if the request is multipart/form-data, or the URL of the query image or document (Data URIs are supported) |
name | null | If set, name for the search. If unset, the filename of the uploaded "file" 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 | |
search_path | <homedir> |
Restrict the search to a specific media path (<homedir>/<path> ). |
mode | "near_duplicate" | Can be near_duplicate to attempt to find the original image(s) the query is derived from or vice-versa, if the matched original is watermarked, detection will be performed. Alternatively can be set to similar to do a faster search in order to find visually similar images which are not necessarily derived from one another or 'leaks'. |
categories | ["default"] | A list to where to search; for image search only; authorized users only. The default may be changed to one of recent (recent images, faster), all (all images, slower). |
transforms | ["scale"] | Geometric transform validation model for images; default is scale (crop/resize no rotation), other allowed values are affine (crop/resize/rotation) or perspective . If mode=leaks , default is ["scale", "perspective"] . |
filter_marked | false | If set, filter the results to only show watermarked results (true) or non-watermarked (false) |
For a search by text, the following parameters are available
Parameter | Default | Description |
---|---|---|
metadata | null | Dict that represent metadata to search |
type | null | String to search only specific media type ("image", "video", "folder") |
filename | null | String that represent the exact filename to search (case sensitive) |
filename__startswith | null | String that represent the begining of the filename to search (case sensitive). Minimum length required = 3 |
sync | true | Run the search in synchronous mode if set |
Response content
The response is one of the following, depending on the sync query parameter:
- For a synchronous search, the response is a Search object with 200 as status code
- For an asynchronous search, the response is a 201 status code (to be checked afterwards)
Multiple search use cases:
Search by binary file
Search with a binary file, by direct upload. (See example)
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>"
}
files = {'file': open('tour-eiffel.jpeg', 'rb')}
response = requests.post("https://imatag.com/api/v4/searches/",
files=files, headers=headers)
curl -X POST \
https://imatag.com/api/v4/searches/ \
-H "Authorization: Token <your api token>" \
-F "file=@tour-eiffel.jpeg"
The above commands returns JSON structured like this:
{
"status": "complete",
"matches": [
{
"id": null,
"created": "2019-11-18T16:40:11.133727Z",
"type": "user",
"watermarked": true,
"image": {
"type": "registered",
"url": "https://static4.imatag.com/54578,15ec5ca69f80719a",
"width": 1280,
"height": 1706,
"thumbnail": "https://static4.imatag.com/211701,81c386bd3eb68eba",
"credit": null,
"media_path": "/api.demo/images/paris/tour-eiffel.jpeg",
"media_url": "https://imatag.com/api/v4/media/api.demo/images/paris/tour-eiffel.jpeg"
}
}
]
}
Search by file url
Search with a remote image, by providing its public URL. (See example)
Alternatively you can perform a request by url
import requests
import json
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "application/json",
}
data = {'file': 'https://imatag.com/api/doc/images/tour-eiffel.jpeg'}
response = requests.post("https://imatag.com/api/v4/searches/",
data=json.dumps(data), headers=headers)
curl -X POST \
https://imatag.com/api/v4/searches/ \
-H "Authorization: Token <your api token>" \
-F "file=https://imatag.com/api/doc/images/tour-eiffel.jpeg"
The above commands returns JSON structured like this:
{
"status": "complete",
"matches": [
{
"id": null,
"created": "2019-11-18T16:39:02.263262Z",
"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,
"media_path": "/api.demo/images/paris/tour-eiffel.jpeg",
"media_url": "https://imatag.com/api/v4/media/api.demo/images/paris/tour-eiffel.jpeg"
}
}
]
}
Search by text
You can search by text. (See example)
You can perform a text search
import requests
import json
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "application/json",
}
data = {
"metadata": {
"user.subject": "Eiffel Tower"
},
"filename" : "tour-eiffel.jpeg",
"type": "image"
}
response = requests.post("https://imatag.com/api/v4/searches/",
data=json.dumps(data), headers=headers)
The above commands returns JSON structured like this:
{
"status": "complete",
"matches": [
{
"id": null,
"created": "2020-10-23T13:41:21.743541Z",
"type": "text",
"query": {
"filename": "tour-eiffel.jpeg",
"type": [
"image"
],
"sync": true,
"metadata": {
"user.subject": "Eiffel Tower"
}
},
"media": {
"metadata": {
"user.subject": "Eiffel Tower",
"user.campaign": "Paris by night"
},
"media_path": "api.demo/images/paris/tour-eiffel.jpeg",
"media_url": "https://imatag.com/api/v4/media/api.demo/images/paris/tour-eiffel.jpeg"
}
}
]
}
Asynchronous search
The search endpoint has a "sync" parameter that can be used to turn on the search asynchronously.
By default, the search is synchronous. An explicit sync
disabling to False
is required to run in async mode.
(See example)
You can also perform an asynchronous search:
import requests
headers = {
"Authorization": "Token <your api token>"
}
files = {'file': open('tour-eiffel.jpeg', 'rb'), 'sync': 0}
response = requests.post("https://imatag.com/api/v4/searches/",
files=files, headers=headers)
curl -X POST \
https://imatag.com/api/v4/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/v4/searches/HTnqefQkb7jq/",
"type": "image",
"image": "https://static2.imatag.com/176044,20b70be705dcf657",
"name": "tour-eiffel.jpg",
"created": "2018-11-07T13:25:52.277479Z",
"status": "pending"
}
Get a search
This endpoint retrieves a specific search.
import requests
headers = {
'Authorization': 'Token <your api token>',
}
response = requests.get('https://imatag.com/api/v4/searches/HTnqefQkb7jq/',
headers=headers)
curl hhttps://imatag.com/api/v4/searches/HTnqefQkb7jq/ \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v4/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/v4/searches/HTnqefQkb7jq/matches/"
}
HTTP Request
GET
https://imatag.com/api/v4/searches/<search_id>/
URL Parameters
Parameter | Required | Description |
---|---|---|
search_id | true | The unique id of the search to retrieve. |
Response description
See Search object
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/v4/searches/', headers=headers)
curl https://imatag.com/api/v4/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/v4/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/v4/searches/qYh98JhK3mUa/matches/"
},
{
"url": "https://imatag.com/api/v4/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/v4/searches/HTnqefQkb7jq/matches/"
}
]
}
HTTP Request
GET
https://imatag.com/api/v4/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) |
Delete an existing search
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.delete("https://imatag.com/api/v4/searches/trhPnufS7NxJ/",
headers=headers)
curl -X DELETE \
https://imatag.com/api/v4/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/v4/searches/<search_id>/
URL Parameters
Parameter | Required | Description |
---|---|---|
search_id | true | The unique id of the search to retrieve. |
Uploads
Data-URI example for the media endpoint
import requests
import base64
import json
headers = {
"Authorization": "Token <your api token>",
"Content-Type": "application/json",
}
lmk = open("./registration.lmk", "rb").read()
lmk_base64 = base64.b64encode(lmk)
data = {
"url": "data:application/lmk;base64,{}".format(lmk_base64),
"metadata": {
"user.isDemo": "True",
"user.campaign": "Visit Paris 2020"
}
}
response = requests.put("https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg",
data=json.dumps(data), headers=headers)
echo "{ \
\"url\": \"data:application/lmk;base64,$(base64 -w 0 registration.lmk)\", \
\"metadata\": { \
\"user.isDemo\": \"True\", \
\"user.campaign\": \"Visit Paris 2020\" \
} \
}" | curl -X PUT \
https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg \
-H "Authorization: Token <your api token>" \
-H "Content-Type: application/json" \
-T -
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v4/media/api.demo/uploads/2018/my-image.jpg",
"path": "api.demo/uploads/2018/my-image.jpg",
"created": "2019-01-02T15:09:17.145580Z",
"disk_usage": 97358,
"type": "image",
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad",
"metadata": {
"user.isDemo": "True",
"user.campaign": "Visit Paris 2020"
},
"image": {
"type": "registered",
"url": "https://static4.imatag.com/20985,28c25e65d3e1baad",
"width": 800,
"height": 500,
"thumbnail": "https://static4.imatag.com/208368,28c25e65d3e1baad"
}
}
Some of our endpoints support direct binary upload when no additional information is required, however others have optional or mandatory additional fields. In this case the file is provided via URL. If the file is not already accessible on a publicly available URL, we offer two options:
The first one is to use a data URI. This requires you to base64 encode your file but limits the number of consecutive API calls. Data-URIs can be used anywhere that require a URL. An example is provided here for a call to the media endpoint.
Alternatively, the uploads endpoint allows you to store temporarily your images on our servers and get URL which can be used on subsequent API calls. This is particularly useful if you need to use the same file in multiple API calls or when you can't do base-64 encoding on your side.
Upload a media
To perform a simple media (image or video) upload, use the endpoint with upload_type=media
(default, can be omitted)
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/v4/uploads/?upload_type=media",
data=img, headers=headers)
curl -X POST \
https://imatag.com/api/v4/uploads/?upload_type=media \
-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 or video on our servers in a temporary collection.
HTTP Request
POST
https://imatag.com/api/v4/uploads/
POST
https://imatag.com/api/v4/uploads/?upload_type=media
By default, without explicit upload_type
query parameter, the simple upload (ie full media file upload)
method will be considered.
Add these HTTP headers:
Header | Description |
---|---|
Content-Type | Set to the MIME media type of the object being uploaded. |
Content-Length | Set to the number of bytes you upload. |
Response description
The response indicates the temporary location of the uploaded asset and its expiration.
Attribute | Description |
---|---|
url | The URL of the uploaded media on our servers |
expiry | Expiration date of the uploaded media on our servers (approximate) |
Upload a large media in chunks
For large file, up to 1Gb, you must use this method to upload a file in several chunks; by sending multiple successive requests.
Initiate a resumable upload session
To allow a file upload in multiple fragments, you first have to initiate a session for a resumable upload,
using the upload_type=resumable
query parameter on the uploads endpoint
import requests
headers = {
"Authorization": "Token <your api token>",
"X-Upload-Content-Disposition": f'name="my-image.jpg"; filename="my-image.jpg"',
"X-Upload-Content-Type": "image/jpeg",
"X-Upload-Content-Length": "5833680",
}
response = requests.post(
"https://imatag.com/api/v4/uploads/?upload_type=resumable",
headers=headers)
upload_session_url = response.headers.get("Location")
curl -i -X POST \
https://imatag.com/api/v4/uploads/?upload_type=resumable \
-H "Authorization: Token <your api token>" \
-H "X-Upload-Content-Disposition: name='my-image.jpg'; filename='my-image.jpg'" \
-H "X-Upload-Content-Type: image/jpeg" \
-H "X-Upload-Content-Length: 5833680"
POST
https://imatag.com/api/v4/uploads/?upload_type=resumable
The following headers are highly recommended to be filled in, so that we have enough information about the file to be uploaded later
Header | Description |
---|---|
X-Upload-Content-Type | Set to the MIME media type of the file to be uploaded. |
X-Upload-Content-Length | Set the total number of bytes of the file to be uploaded. |
X-Upload-Content-Disposition | Set the name of the file to be uploaded. |
Response description
If successful, the response includes a 200
status code, with the Location
header
containing the resumable session URI
Upload the data in multiple chunks
Once you have initiated the resumable upload session, you will be able to upload the file date in multiple chunks.
The chunk size cannot exceed 256Mb.
Use the upload URI saved from previous step, to upload the data:
import requests
headers = {
"Authorization": "Token <your api token>",
"Content-Disposition": f'name="my-image.jpg"; filename="my-image.jpg"',
"Content-Type": "image/jpeg",
"Content-Length": "2097152",
"Content-Range": "0-2097151/5833680",
}
chunk = open("./original.jpeg", "rb").read(2*1024*1024)
response = requests.put(
"https://imatag.com/api/v4/uploads/?upload_id=<uuid>",
headers=headers)
curl -i -X PUT \
https://imatag.com/api/v4/uploads/?upload_id=resumable \
-H "Authorization: Token <your api token>" \
-H "Content-Disposition: name='my-image.jpg'; filename='my-image.jpg'" \
-H "Content-Type: image/jpeg" \
-H "Content-Length: 2097152" \
-H "Content-Range: 0-2097151/5833680" \
--data-binary @- < ./chunk_file_location
PUT
https://imatag.com/api/v4/uploads/?upload_id=<uuid>
providing the headers:
Header | Description |
---|---|
Content-Type | Set to the MIME media type of the full media file. |
Content-Length | Set the number of bytes you're uploading in the current request. |
Content-Range | Set the range of bytes in the overall media of the current chunk being uploaded, as bytes <chunk fist byte>-<chunk last byte>/<total file size> . An example Content-Range is Content-Range: bytes 0-8388607/20000000 . |
Content-Disposition | Set the name of the full file. |
The Content-Range header is providing the information about the begin & end of the current chunk as well as the total file size.
You have to repeat this step until last chunk is uploaded.
Response description
- If the request succeeds, the server responds with 308 Resume Incomplete. The response contains a Range header. It indicates the total number of bytes received from the beginning of the upload session.
An example Range is Range: bytes=0-4194304
- If the request succeeds with the last chunk, the server responds with 200. The response body thus contains the same information as for a simple media upload:
Attribute | Description |
---|---|
url | The URL of the uploaded media on our servers |
expiry | Expiration date of the uploaded media on our servers (approximate) |
Watermarking
The watermarking endpoint allows you to apply an invisible watermark on a provided image 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 an image 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/v4/watermarking/",
json=data, headers=headers)
curl -X POST \
https://imatag.com/api/v4/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/v4/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.
- A JSON data with the following attributes:
Attribute | Required | Description |
---|---|---|
url | true | The URL of the asset "http://..."` |
sync | false | The sync call of the api (true or false, default = true) |
timeout | false | The timeout call of the api |
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) |
registration | The URL of the registration data that should be sent on the media endpoint |
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 an 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/v4/watermarking/",
data=img, headers=headers)
curl -X POST \
https://imatag.com/api/v4/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
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"
}
Detect a watermarked file
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/v4/media/api.demo/images/paris/tour-eiffel.jpeg"
}
response = requests.post(
"https://imatag.com/api/v4/watermarking/detect/",
json=data, headers=headers)
curl -X POST \
https://imatag.com/api/v4/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/v4/watermarking/detect/
The endpoint allows verifying if an image, aka query, is a watermarked copy of the image from the registration file.
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 |
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. |
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) |
transform | false | Geometric transform validation model for images; default is scale (crop/resize no rotation), other allowed values are affine (crop/resize/rotation), perspective or none . |
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. |
payload | Payload value for images watermarked with payload mode. Omitted if not applicable. |
Get the encryption key
Get the encryption key
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get(
"https://imatag.com/api/v4/watermarking/key/",
headers=headers)
curl https://imatag.com/api/v4/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/v4/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 |
Helpful Resources
This section provides additional resources and practical tips to enhance your experience with our API. From pagination and error handling to image formats and watermark details, you'll find useful explanations and clarifications. A glossary is also included to help you navigate technical terms with ease.
Watermark detection information
Statistical significance
Throughout this API and IMATAG in general, images are said to be "watermarked" if the detection test result has a P-value lower than a fixed probability of error threshold (IMATAG communicates this threshold upon request to clients).
For security reasons, IMATAG does not normally provide the actual P-value of any given match and it is therefore not accessible via the API. If you have a legal reason that requires this p-value for a given query, please contact IMATAG and we will provide you the information.
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.
By default, a page will contain 100 objects at most. You can change that number by specifying page_size=X
as query parameter in any url.
The maximum number of objects per page allowed is 100.
Image formats
Our API is currently limited to some images format only:
- JPEG: Without restriction.
- PNG: Watermarked except for indexed colors, fully supported everywhere else.
- GIF: Watermarking is not supported, fully supported everywhere else. Limited to first frame if animated.
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 |
PNG | image/png |
GIF | image/gif |
TIFF | image/tiff |
Output formats
By default, responses data are returned as json
.
You can choose to specify the output format as query parameter ?format=<format>
.
We currently support json format.
Error handling recommendations
4XX errors
- 429: Wait for the suggested duration before retrying.
- 409: If you are not in the case above, it depends whether this is something that can normally happen with your process. In any case you should be able to automate the behavior (ignore/rename/replace)
- other 4xx, investigate and contact us if necessary.
5XX errors and network errors
Retry after 1h (or more)
Versioning
The versioning of the API is specified as part of the URI.
For instance, in order to use v4 of the API the request URI should begin with /api/v4
followed by a specific endpoint.
https://imatag.com/api/v4/<endpoint>
Supported versions are:
API Version | Documentation link |
---|---|
v1 (deprecated) | v1 |
v2 (stable) | v2 |
v3 (stable) | v3 |
v4 (current) | v4 |