Introduction
Welcome to the IMATAG API v3!
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. There are 3 ways to authenticate yourself.
API key
IMATAG uses API keys to allow access to the API. Your API key is available in your account settings on IMATAG. This is the simplest way to authenticate but it's also the less secure as your token will be the same ad vitam aeternam.
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 API expects the API key to be included in all requests to the server in the authorization header as follow:
Authorization: Token putyourapitokenhere
OAuth2
You can find the OAuth specification at https://www.oauth.com/.
Imatag support OAuth authentication using client credential
only.
It is suitable for machine-to-machine authentication.
Create an application
Create an application
import requests
url = "https://app.imatag.com/api/v3/account/oauth/applications/"
response = requests.post(url, data={"name": "my_app"}, headers={"Authorization": "Token your_api_key"})
curl -X POST https://app.imatag.com/api/v3/account/oauth/applications/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Token your_api_key' \
-d '{"name":"my_app"}'
You'll get a response like this :
{
"id": 42,
"name": "your_app_name",
"client_id": "your_client_id",
"client_secret": "your_client_secret"
}
You will have to provide your api key that you can find in your account settings.
HTTP Request
POST
https://imatag.com/api/v3/account/oauth/applications/
Request content
- The content-type of the request must be
application/json
.
Attribute | Required | Description |
---|---|---|
name | True | The name of your application |
Response description
Attribute | Description |
---|---|
id | Id of your application |
name | Name of your application |
client_id | Your client_id for this application |
client_secret | Your client_secret for this application |
Get access 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 |
Make API requests
The access token should be used as follows:
import requests
headers = {"Authorization": "Bearer your_access_token"}
response = requests.get("https://imatag.com/api/v3/endpoint/", headers=headers)
curl "https://imatag.com/api/v3/endpoint/" \
-H "Authorization: Bearer your_access_token"
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.
Note that the access token expires one hour after its creation. To get another one, simply follow again the get access token process
List applications
List applications
import requests
url = "https://app.imatag.com/api/v3/account/oauth/applications/"
response = requests.get(url, headers={"Content-Type": "application/json", "Authorization": "Bearer your_access_token"})
curl -X GET http://127.0.0.1:8000/api/v3/account/oauth/applications/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Token your_access_token'
You'll get a response like this :
{
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": "my_app_1",
"client_id": "client_id_1",
"created": "2023-01-19T16:49:49.470412+01:00"
},
{
"id": 2,
"name": "my_app_2",
"client_id": "client_id_2",
"created": "2023-01-19T16:50:17.485791+01:00"
}
]
}
You can list your applications. To do so, proceed as follows :
HTTP Request
GET
https://imatag.com/api/v3/account/oauth/applications/
Response description
Attribute | Description |
---|---|
next | Next page link |
previous | Previous page link |
results | List of apps |
Get applications
Get application detail
import requests
url = "https://app.imatag.com/api/v3/account/oauth/applications/app_id/"
response = requests.get(url, headers={"Content-Type": "application/json", "Authorization": "Bearer your_access_token"})
curl -X GET https://app.imatag.com/api/v3/account/oauth/applications/app_id/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Token your_access_token'
You'll get a response like this :
{
"id": "app_id",
"name": "my_app",
"client_id": "client_id",
"created": "2023-01-19T16:49:49.470412+01:00"
}
You can get an application detail. To do so, proceed as follows :
HTTP Request
GET
https://imatag.com/api/v3/account/oauth/applications/app_id/
Application object
Attribute | Description |
---|---|
id | Application id |
name | Name of the application |
client_id | Client id of the application |
created | Date of creation |
Delete an application
Delete an application
import requests
url = "https://app.imatag.com/api/v3/account/oauth/applications/app_id/"
response = requests.delete(url, headers={"Authorization": "Bearer your_access_token"})
curl -X DELETE https://app.imatag.com/api/v3/account/oauth/applications/app_id/ \
-H 'Authorization: Token your_access_token'
You'll get an empty body response with a 204 status code.
To revoke an application authorization you can delete it. To do so, proceed as follows :
HTTP Request
DELETE
https://imatag.com/api/v3/account/oauth/applications/app_id/
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.
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.
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 status 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.
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 |
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 the following formats:
- json
- xml
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.
List of status codes
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. |
422 | Unprocessable entity -- The request has valid content type and its syntax is correct but we were unable to process the contained data. |
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. |
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)
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 "Software download" 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
imatag_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 or PNG format |
<output_image.jpg> | The full-resolution output watermarked image, in same format as input |
<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.
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.
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 |
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/v3/account/",
headers=headers)
curl -X GET \
https://imatag.com/api/v3/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/v3/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/v3/account/settings/",
headers=headers)
curl -X GET \
https://imatag.com/api/v3/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/v3/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/v3/account/download/",
headers=headers)
curl -X GET \
https://imatag.com/api/v3/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/v3/account/download/key/"
},
"software": {
"lamark": "/api/v3/account/download/software/X.Y.Z/lamark",
"lamark.exe": "/api/v3/account/download/software/X.Y.Z/lamark.exe"
}
}
HTTP Request
GET
https://imatag.com/api/v3/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 |
Aggregations
This endpoint allows you to view aggregated information about matches.
There are different endpoints that can be used to get these aggregations.
List all endpoints
This endpoint allows to retrieve the list of aggregations endpoints available. Please note that any endpoint listed can be renamed, removed or added at any time.
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v3/aggregations/", headers=headers)
curl -X GET \
https://imatag.com/api/v3/aggregations/ \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
[
{
"url": "/api/v3/aggregations/group-path/",
"name": "group-path"
},
{
"url": "/api/v3/aggregations/group-site-path/",
"name": "group-site-path"
},
{
"url": "/api/v3/aggregations/group-site-path-pageurl/",
"name": "group-site-path-pageurl"
}
]
HTTP Request
GET
https://imatag.com/api/v3/aggregations/
Response description
The response is a list, where each element is a dict containing the name and url of an aggregation.
Access to aggregation data
You can access to a specific aggregation, using any of the endpoints previously listed.
HTTP Request
GET
https://imatag.com/api/v3/aggregations/<aggregation>/
URL Parameters
Parameter | Required | Description |
---|---|---|
aggregation | true | The name of the specific aggregation to query |
As a reminder, the list of aggregation names can be retrieved using the list all endpoints.
Query Parameters
You can filter the response using query parameters with any allowed field as:
Parameter | Description |
---|---|
<field> =... |
The field value is equal to the value |
!<field> =... |
The field value is different from the value |
<field> __isnull=... |
The field value is null |
<field> __startswith=... |
The field value starts with the value |
<field> __in=... |
The field value is within the comma separated list |
<field> __gt=... |
The field value is greather than the value |
<field> __lt=... |
The field value is lower than the value |
<field> __gte=... or <field> >=... |
The field value is greater than or equal to the value |
<field> __lte=... or <field> <=... |
The field value is lower than or equal to the value |
You can also export the data in csv
format, in addition of the default output formats supported.
To do so, you have to specify format=csv
as a query parameter.
Due to format limitation, data can be slightly different (e.g. there is no list nor sub object in a csv format).
Response description
The response is a dict with pagination that contains a list of objects. The content of the response will be different for each aggregation endpoint. All aggregations will contain different data, but some are shared with all of them:
Field | type | can be used in query filter | description |
---|---|---|---|
_id | String | yes | unique identifier of the object |
_version | Integer | no | version of the object (number of modifications) |
group | Integer | yes | owner |
type | Enum | yes | 0 : unknown 1 : aggregation by video 2 : aggregation by image 3 : aggregation by crawler 4 : aggregation by site |
created | Date | yes | date of creation of the object |
updated | Date | yes | date of the last update of the object |
export | Boolean | yes | indicate whether the object can be exported in csv format |
deleted | Boolean | no | should always be false |
tags | List of string | yes | tag that you can add to the object |
Access to a single aggregation object
This endpoint provides access to a specific aggregation object, from its unique identifier.
Endpoint
GET
https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get(
"https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/",
headers=headers)
curl -X GET \
https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/ \
-H "Authorization: Token <your api token>"
URL Parameters
Parameter | Required | Description |
---|---|---|
aggregation | true | The name of the specific aggregation to query |
_id | true | The unique identifier of the aggration object |
Response description
The content of the response is the same as in the list of objects, but the response contains only one object.
Modify the object
To modify the object, you can use the PATCH
method to change the value of some fields.
PATCH
https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/
import requests
headers = {
"Authorization": "Token <your api token>",
}
data = {
"tags": ["tag1", "tag2"],
"export": False
}
response = requests.patch(
"https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/",
json=data, headers=headers)
curl -X PATCH \
https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/ \
-H "Content-Type: application/json" \
-H "Authorization: Token <your api token> \
--data '{"tags": ["tag1", "tag2"], "export": false}'
Request content
Attribute | Required | Description |
---|---|---|
export | false | Flag for allowing the csv export of the aggregation data |
tags | false | List of tags of the aggregation object |
Access to a single field of an object
This endpoint provides access to a specific field object (or to modify it).
You'll need the _id
of the object and the name of the field
.
You can also access elements in a list by index: field.<index>
(e.g. tags.0
)
Endpoint
GET
https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/<field>/
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get(
"https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/<field>/",
headers=headers)
curl -X GET \
https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/<field>/ \
-H "Authorization: Token <your api token>"
URL Parameters
Parameter | Required | Description |
---|---|---|
aggregation | true | The name of the specific aggregation to query |
_id | true | The unique identifier of the aggration object |
field | true | The name of the field to access; use field. |
Response description
The content of the response is the value of the field.
Modify the field value
import requests
headers = {
"Authorization": "Token <your api token>",
}
data = {
"content": ["tag1", "tag2"]
}
response = requests.put(
"https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/tags/",
json=data, headers=headers)
curl -X PUT \
https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/tags/ \
-H "Content-Type: application/json" \
-H "Authorization: Token <your api token>" \
--data '{"content": ["tag1", "tag2"]}'
To modify a field value, you have two options:
PUT
https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/<field>/
: replaces the content of the field with a new valuePOST
https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/<field>/
: append a new value to a list (no duplication allowed).
The content of the request must be JSON with following attributes:
Attribute | Required | Description |
---|---|---|
content | true | The new value of the field |
Remove a field value
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.delete(
"https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/tags.0/",
headers=headers)
curl -X DELETE \
https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/tags.0/ \
-H "Authorization: Token <your api token>"
This endpoint allows removal of:
- a field value,
- an item from a list, at a specified index.
DELETE
https://imatag.com/api/v3/aggregations/<aggregation>/<_id>/<field>/
:
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/v3/crawling/sessions/
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v3/crawling/sessions/", headers=headers)
curl https://imatag.com/api/v3/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/v3/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/v3/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/v3/crawling/sessions/<session_id>/
import requests
headers = {
'Authorization': 'Token <your api token>',
}
response = requests.get('https://imatag.com/api/v3/crawling/sessions/1/',
headers=headers)
curl https://imatag.com/api/v3/crawling/sessions/1/ \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"id" : 1,
"batches" : "https://imatag.com/api/v3/crawling/sessions/1/batches/",
"url" : "https://imatag.com/api/v3/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
}
URL Parameters
Parameter | Required | Description |
---|---|---|
session_id | true | The unique id of the session to retrieve information on. |
Response description
Create a new session
HTTP Request
POST
https://imatag.com/api/v3/crawling/sessions/
import requests
headers = {
'Authorization': 'Token <your api token>',
}
response = requests.post('https://imatag.com/api/v3/crawling/sessions/',
json={'url': 'http://imatag.com' }, headers=headers)
curl -X POST \
https://imatag.com/api/v2/crawling/sessions/ \
-H "Content-Type: application/json" \
-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/v3/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/v3/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/v3/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/v3/crawling/sessions/1/",
headers=headers)
curl -X DELETE \
https://imatag.com/api/v3/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 | Dict 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 | Dict 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 | Dict 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 | Dict 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/v3/crawling/sessions/<session_id>/batches/
URL Parameters
Parameter | Required | Description |
---|---|---|
session_id | true | The unique id of the session to retrieve batches for. |
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v3/crawling/sessions/1/batches/", headers=headers)
curl https://imatag.com/api/v3/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/v3/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/v3/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/v3/crawling/batches/
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v3/crawling/batches/", headers=headers)
curl https://imatag.com/api/v3/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/v3/crawling/sessions/1/",
"url" : "https://imatag.com/api/v3/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/v3/crawling/batches/13/',
headers=headers)
curl https://imatag.com/api/v3/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/v3/crawling/sessions/1/",
"images" : {
"log" : "https://static1.imatag.com/54682,1729c13dd6694192",
"count" : 2647
},
"url" : "https://imatag.com/api/v3/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/v3/crawling/batches/<batch_id>/
URL Parameters
Parameter | Required | Description |
---|---|---|
batch_id | true | The unique id of the batch to retrieve information on. |
Response description
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/v3/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/v3/domains/blacklist/",
json=data, headers=headers)
curl -X POST \
https://imatag.com/api/v3/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/v3/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/v3/domains/blacklist/",
headers=headers)
curl -X GET \
https://imatag.com/api/v3/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/v3/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/v3/domains/blacklist/",
data=json.dumps(data), headers=headers)
curl -X DELETE \
https://imatag.com/api/v3/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/v3/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
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.
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/v3/matches/web/
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v3/matches/web/", params={
'watermarked': True, 'date': '2018-08-02'},
headers=headers)
response = requests.get("https://imatag.com/api/v3/matches/web/", params={
'watermarked': True, 'date_gt': '2018-08-01', 'date_lte': '2018-08-02T12:45:00Z'},
headers=headers)
curl 'https://imatag.com/api/v3/matches/web/?watermarked=true&date=2018-08-02' \
-H "Authorization: Token <your api token>"
curl 'https://imatag.com/api/v3/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/v3/matches/web/?cursor=cD0xNTczNTgwNTgyNzQ5JmM9MzY4NTg%3D",
"previous": null,
"results": [
{
"id": 190113962,
"url": "https://imatag.com/api/v3/matches/image/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/",
"session_id": 5,
"query_format": "jpeg",
"query_width": 833,
"query_height": 500,
"image": {
"type": "registered",
"url": "https://static1.imatag.com/54578,15ec695538df826a",
"width": 1280,
"height": 853,
"format": "jpeg",
"thumbnail": "https://static1.imatag.com/206837,8110da3066effc82",
"credit": null,
"media_path": "api.demo/images/new-york/nyc-taxis.jpeg",
"media_url": "https://imatag.com/api/v3/media/api.demo/images/new-york/nyc-taxis.jpeg",
"metadata": {
"user.demo_key": "this is the value"
}
},
"domain": "p-umc.com"
},
"..."
]
}
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 domains that are not in the blacklist will be returned (ie results for blacklisted domains are filtered out) |
session_id | null | If set, only results originating from this Crawling Session id 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 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 is recorded for an exclusive image (optional boolean); at the time of the record |
query_url | The original URL of the query media |
query_width | The width of the query media |
query_height | The height 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) |
session_id | ID of the from this Crawling Session that generated this match |
domain | Full domain of the query matched |
Additionally, image matches have these extra fields:
Attribute | Description |
---|---|
query_format | format of the query image (e.g. jpeg or png ) |
image | The image object (see Image object) matched with the query |
Additionally, video matches have these extra fields:
Attribute | Description |
---|---|
video | The video object (see Video object) matched with the query |
query_video_start_time | start time in seconds of the match in the query video |
query_video_end_time | end time in seconds of the match in the query video |
query_video_match_duration | duration in seconds of the match in the query video |
matched_video_start_time | start time in seconds of the match in the matched video |
matched_video_end_time | end time in seconds of the match in the matched video |
matched_video_match_duration | duration in seconds of the match in the matched video |
Press Matches
This endpoint lists all matches found in the press.
HTTP Request
GET
https://imatag.com/api/v3/matches/press/
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v3/matches/press/", headers=headers)
curl https://imatag.com/api/v3/matches/press/ \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "94457659",
"url": "https://imatag.com/api/v3/matches/images/94457659/",
"created": "2018-08-03T12:35:23.371022Z",
"type": "press",
"watermarked": true,
"issue": {},
"page_number": 1,
"image": {
"type": "registered",
"url": "https://static2.imatag.com/54580,15ec6954eac4981b",
"width": 1280,
"height": 904,
"thumbnail": "https://static3.imatag.com/211697,70014e5e3e082b02",
"credit": null,
"media_url": "https://imatag.com/api/v3/media/api.demo/images/new-york/brooklyn-bridge.jpeg"
}
}
]
}
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/v3/matches/credit/
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.get("https://imatag.com/api/v3/matches/credit/", headers=headers)
curl https://imatag.com/api/v3/matches/credit/ \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "95998502",
"url" : "https://imatag.com/api/v3/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 domains 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 Text 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 |
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/v3/media/api.demo/images', headers=headers)
curl https://imatag.com/api/v3/media/api.demo/images \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v3/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/v3/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/v3/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/v3/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/v3/media/api.demo/images/paris/tour-eiffel.jpeg',
headers=headers)
curl https://imatag.com/api/v3/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/v3/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/v3/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
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/v3/media/api.demo/uploads/2018/my-image.jpg",
data=lmk, headers=headers)
curl -X PUT \
https://imatag.com/api/v3/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/v3/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/v3/media/api.demo/uploads/2018/my-image.jpg",
data=json.dumps(data), headers=headers)
curl -X PUT \
https://imatag.com/api/v3/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/v3/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
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.
HTTP Request
PUT
https://imatag.com/api/v3/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/v3/media/api.demo/uploads/2018/my-image.jpg",
data=json.dumps(data), headers=headers)
curl -X PATCH \
https://imatag.com/api/v3/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/v3/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/v3/media/api.demo/uploads/2018/my-image.jpg",
data=image, headers=headers)
curl -X PUT \
https://imatag.com/api/v3/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/v3/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/v3/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/v3/media/api.demo/uploads/2018/my-image.jpg",
data=image, headers=headers)
curl -X PUT \
https://imatag.com/api/v3/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/v3/media/api.demo/uploads/original_video.mp4",
"secret": "my secret video",
"payload": 5,
"max_payload": 20,
}
response = requests.put("https://imatag.com/api/v3/media/api.demo/uploads/watermarked_video.mp4",
data=json.dumps(data), headers=headers)
curl -X PUT \
https://imatag.com/api/v3/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/v3/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/v3/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/v3/media/api.demo/uploads/2018",
data=lmk, headers=headers)
curl -X PUT \
https://imatag.com/api/v3/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/v3/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/v3/media/api.demo/uploads/2018/my-image.jpg",
headers=headers)
curl -X DELETE \
https://imatag.com/api/v3/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/v3/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/v3/media/api.demo/uploads/2018",
headers=headers,
)
curl -X PUT \
https://imatag.com/api/v3/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/v3/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/v3/media/api.demo/uploads/2018",
headers=headers)
curl -X DELETE \
https://imatag.com/api/v3/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/v3/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/v3/media/_move/",
json=data, headers=headers)
curl -L -X POST 'https://imatag.com/api/v3/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/v3/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 Web 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. |
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/v3/searches/', headers=headers)
curl https://imatag.com/api/v3/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/v3/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/v3/searches/qYh98JhK3mUa/matches/"
},
{
"url": "https://imatag.com/api/v3/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/v3/searches/HTnqefQkb7jq/matches/"
}
]
}
HTTP Request
GET
https://imatag.com/api/v3/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/v3/searches/HTnqefQkb7jq/',
headers=headers)
curl hhttps://imatag.com/api/v3/searches/HTnqefQkb7jq/ \
-H "Authorization: Token <your api token>"
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v3/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/v3/searches/HTnqefQkb7jq/matches/"
}
HTTP Request
GET
https://imatag.com/api/v3/searches/<search_id>/
URL Parameters
Parameter | Required | Description |
---|---|---|
search_id | true | The unique id of the search to retrieve. |
Response description
See Search object
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/v3/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). |
parameters | A dict of parameters (see under) | |
parameters.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"] . |
parameters.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/v3/searches/",
files=files, headers=headers)
curl -X POST \
https://imatag.com/api/v3/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/v3/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/v3/searches/",
data=json.dumps(data), headers=headers)
curl -X POST \
https://imatag.com/api/v3/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/v3/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/v3/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/v3/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/v3/searches/",
files=files, headers=headers)
curl -X POST \
https://imatag.com/api/v3/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/v3/searches/HTnqefQkb7jq/",
"type": "image",
"image": "https://static2.imatag.com/176044,20b70be705dcf657",
"name": "tour-eiffel.jpg",
"created": "2018-11-07T13:25:52.277479Z",
"status": "pending"
}
Delete an existing search
import requests
headers = {
"Authorization": "Token <your api token>",
}
response = requests.delete("https://imatag.com/api/v3/searches/trhPnufS7NxJ/",
headers=headers)
curl -X DELETE \
https://imatag.com/api/v3/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/v3/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/v3/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/v3/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/v3/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 an image or video
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/v3/uploads/",
data=img, headers=headers)
curl -X POST \
https://imatag.com/api/v3/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 or video on our servers in a temporary collection.
HTTP Request
POST
https://imatag.com/api/v3/uploads/
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) |
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/v3/watermarking/",
json=data, headers=headers)
curl -X POST \
https://imatag.com/api/v3/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/v3/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 when watermarking images only |
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/v3/watermarking/",
data=img, headers=headers)
curl -X POST \
https://imatag.com/api/v3/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/v3/media/api.demo/images/paris/tour-eiffel.jpeg"
}
response = requests.post(
"https://imatag.com/api/v3/watermarking/detect/",
json=data, headers=headers)
curl -X POST \
https://imatag.com/api/v3/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/v3/watermarking/detect/
The endpoint allows verifying if an image, aka 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. |
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 . |
One of registration
or secret
is required, they are mutually exclusive. If secret
is set, original
is required as well.
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/v3/watermarking/key/",
headers=headers)
curl https://imatag.com/api/v3/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/v3/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 |
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/v3/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/v3/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/v3/media/api.demo/uploads/2018/my-image.jpg",
data=json.dumps(data), headers=headers)
For many companies, 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.
Leaks
For IMATAG Leaks users, this section indicates how to use the IMATAG API to be able to manage their campaigns programmatically.
Leaks is composed of two main concepts:
- campaign: A campaign allows to handle a set of images for a list of recipients
- recipient: A recipient is a person who will be receiving a personal watermarked copy of each image of the campaign
Folders structure
|-- <home directory>
|-- leaks-campaigns
|-- <campaign name>
|-- [.originals]
|-- <original image name>
|-- ...
|-- <recipient name>
|-- <watermarked images name>
|-- ...
|-- ...
|-- ...
When using the CLI to create their campaign, the folder & media tree structure must be followed strictly as describe in the right panel →.
With a flat path, it should follow the pattern: <home>/leaks-campaigns/<campaign name>/<recipient name>/<media name>
Create a campaign
Create the campaign
Create the campaign
curl -L -X PUT 'https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}' \
-H 'Content-Type: application/x-directory' \
-H 'Authorization: Token <your api token>'
import requests
url = "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}"
payload={}
headers = {
'Content-Type': 'application/x-directory',
'Authorization': 'Token <your api token>'
}
response = requests.request("PUT", url, headers=headers, data=payload)
print(response.text)
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/my-first-campaign",
"path": "api.demo/leaks-campaigns/my-first-campaign",
"created": "2022-01-19T15:34:19.279138Z",
"type": "folder",
...
}
First, You need to manually create the campaign. see how to create a folder
PUT
https://imatag.com/api/v3/media/<home>/leaks-campaigns/<campaign>
Then, the campaign folder must contain some metadata to be fully functional by our system:
user.type="campaign"
Set the campaign metadata
curl -L -g -X PATCH 'https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}' \
--data-raw '{
"metadata": {
"user.type": "campaign",
"user.status": "draft"
}
}'
import requests
url = "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}"
payload = '''{
"metadata": {
"user.type": "campaign",
"user.status": "draft"
}
}'''
headers = {}
response = requests.request("PATCH", url, headers=headers, data=payload)
print(response.text)
see how to modify the folder metadata
Upload your original files
Upload your original files
curl -L -g -X PUT 'https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}/.originals/{{image.jpeg}}' \
-H 'Content-Type: image/jpeg' \
-H 'Authorization: Token <your api token>' \
--data-binary '@/path/to/your/original/image.jpeg'
import requests
url = "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}/.originals/{{image.jpeg}}"
payload="<file contents here>"
headers = {
'Content-Type': 'image/jpeg',
'Authorization': 'Token <your api token>'
}
response = requests.request("PUT", url, headers=headers, data=payload)
print(response.text)
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/my-first-campaign/.originals/my-image.jpeg",
"path": "api.demo/leaks-campaigns/my-first-campaign/.originals/my-image.jpeg",
"created": "2022-01-19T16:02:49.648494Z",
"disk_usage": 82780,
"type": "image",
"thumbnail": "http://static2.imatag.com/21,1526522dff",
"metadata": {},
"image": {
"type": "registered",
"url": "http://static2.imatag.com/12,14d5b20155",
"width": 1280,
"height": 853,
"format": "jpeg",
"thumbnail": "http://static2.imatag.com/21,1526522dff",
"credit": null
}
}
You have two options, for uploading your original assets.
The preferred option is to upload your original assets into the .originals
sub-folder of your campaign:
<home>/leaks-campaigns/<campaign name>/.originals/
It mainly allows to upload your assets only once, when dealing with a large number of recipients.
Upload your original image by using the additional
argument mark: True
in the json payload alongside the request content:
You will have to use image.url
, from the response, as the original image URL.
The second solution is to use the dedicated endpoint for uploading the image temporary to our servers. Then use that temporary URL to watermark and register copies.
Create the recipients
Create the recipients
curl -L -g -X PUT 'https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}/{{recipient}}' \
-H 'Content-Type: application/x-directory' \
-H 'Authorization: Token <your api token>'
import requests
url = "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}/{{recipient}}"
payload={}
headers = {
'Content-Type': 'application/x-directory',
'Authorization': 'Token <your api token>'
}
response = requests.request("PUT", url, headers=headers, data=payload)
print(response.text)
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/my-first-campaign/jondoe",
"path": "api.demo/leaks-campaigns/my-first-campaign/jondoe",
"created": "2022-01-19T16:05:27.244851Z",
"disk_usage": 0,
"type": "folder",
"thumbnail": null,
"metadata": {},
"children_count": 0,
"subfolders_count": 0,
"media_count": 0
}
Create recipients sub-folders under the campaign folder. see how to create a folder
Generate watermarked copies
Generate watermarked copies
curl -L -g -X PUT 'https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}/{{recipient}}/{{watermark.jpeg}}' \
-H 'Authorization: Token <your api token>' \
-H 'Content-Type: application/json' \
--data-raw '{
"url": "{{original image URL}}",
"mark": true,
"metadata": {
"user.campaign": "{{campaign}}",
"user.recipient": "{{recipient}}"
}
}'
import requests
import json
url = "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}/{{recipient}}/marked.jpeg"
payload = json.dumps({
"url": "{{original image URL}}",
"mark": True,
"metadata": {
"user.campaign": "{{campaign}}",
"user.recipient": "{{recipient}}"
}
})
headers = {
'Authorization': 'Token <your api token>',
'Content-Type': 'application/json'
}
response = requests.request("PUT", url, headers=headers, data=payload)
print(response.text)
The above command returns JSON structured like this:
{
"url": "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/my-first-campaign/jondoe/marked.jpeg",
"path": "api.demo/leaks-campaigns/my-first-campaign/jondoe/marked.jpeg",
"created": "2022-01-19T16:22:50.059784Z",
"disk_usage": 82780,
"type": "image",
"thumbnail": "http://static2.imatag.com/16,182d9e9358",
"metadata": {
"user.recipient": "jondoe",
"user.campaign": "my-first-campaign"
},
"image": {
"type": "registered",
"url": "http://static2.imatag.com/26,17e965ff77",
"width": 1280,
"height": 853,
"format": "jpeg",
"thumbnail": "http://static2.imatag.com/16,182d9e9358",
"credit": null
}
}
You will have to create n watermark copies, one for each recipient, for each image of the campaign.
To do so, we'll consider, you have the original images URLs, not yet watermarked, from your .originals
folder (or temporary URL).
You can watermark and register a copy, at once, using the media registration endpoint,
providing the extra parameter mark
to true
.
It's best to also add metadata for registering your new watermark copy, with:
user.campaign="<name of the campaign>"
user.recipient="<name of the recipient>"
user.X="<value>
for any other metadata that you want to add
This metadata will be useful to you when trying to find a potential leak. When a leak is detected, the metadata will be provided back to you. With both the campaign & recipient names in the metadata, you will thus be able to easily know/identify the leak.
Set the campaign as complete
Set the campaign as complete
curl -L -g -X PATCH 'https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}' \
-H 'Authorization: Token <your api token>' \
-H 'Content-Type: application/json' \
--data-raw '{
"metadata": {
"user.type": "campaign",
"user.status": "done"
}
}'
import requests
import json
url = "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}"
payload = json.dumps({
"metadata": {
"user.type": "campaign",
"user.status": "done"
}
})
headers = {
'Authorization': 'Token <your api token>',
'Content-Type': 'application/json'
}
response = requests.request("PATCH", url, headers=headers, data=payload)
print(response.text)
Once all images have been watermarked, for each user, you have to set the campaign as complete (done
).
This will allow downloading watermarked assets, and forbid for campaign modifications.
This can be done by simply updating the campaign metadata: user.status="done"
.
Download the watermarked copies
Download the watermarked copies
curl -L -g -X GET 'https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}/_archive/zip/' \
-H 'Authorization: Token <your api token>' \
-o my-archive.zip
import requests
url = "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/{{campaign}}/_archive/zip/"
payload={}
headers = {
'Authorization': 'Token <your api token>'
}
response = requests.request("GET", url, headers=headers, data=payload)
open('my-campaign.zip', 'wb').write(response.content)
You can either download:
- all watermarked versions for all your recipients, as a ZIP file. Each recipient's images will be in a dedicated folder.
GET
https://imatag.com/api/v3/media/<home>/leaks-campaigns/<campaign>/_archive/zip/
- watermarked images for a single recipient only. All images will be at root level of the ZIP file.
GET
https://imatag.com/api/v3/media/<home>/leaks-campaigns/<campaign>/<recipient>/_archive/zip/
Detect a leak
When you have a suspicious image, ie potentially leaked, you can use the searches endpoint to perform a watermark search. The search will be performed across all your watermarked copies from all of your campaigns. When a watermark is found, we will identify the matches and reveal the leak details (campaign & recipient).
First you have to upload temporarily the suspicious image onto our servers, with the upload endpoint.
POST
https://imatag.com/api/v3/uploads/
Upload the suspicious image onto our servers
curl -L -X POST 'https://imatag.com/api/v3/uploads/' \
-H 'Content-Type: image/jpeg' \
-H 'Authorization: Token <your api token>' \
--data-binary '@/path/to/your/suspicious/image.jpeg'
import requests
url = "https://imatag.com/api/v3/uploads/"
payload="<file contents here>"
headers = {
'Content-Type': 'image/jpeg',
'Authorization': 'Token <your api token>'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
The above command returns JSON structured like this:
{
"url": "http://static2.imatag.com/4,1a0689a16a",
"expiry": "2022-01-20T14:37:41Z"
}
This will return you a url
of the image, that you can use to make the search query.
POST
https://imatag.com/api/v3/searches/
Then perform the search, using the URL from the previous call.
curl -L -X POST 'https://imatag.com/api/v3/searches/' \
-H 'Authorization: Token <your api token>' \
-H 'Content-Type: application/json' \
--data-raw '{
"file": "http://static2.imatag.com/4,1a0689a16a",
"mode": "leaks"
}'
import requests
import json
url = "https://imatag.com/api/v3/searches/"
payload = json.dumps({
"file": "http://static2.imatag.com/4,1a0689a16a",
"mode": "leaks"
})
headers = {
'Authorization': 'Token <your api token>',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
The above command returns JSON structured like this:
{
"status": "complete",
"matches": [
{
"id": null,
"created": "2022-01-21T12:40:57.699230Z",
"type": "user",
"metadata": {
"user.campaign": "my-first-campaign",
"user.recipient": "jondoe"
},
"watermarked": true,
"query_format": null,
"image": {
"type": "registered",
"url": "http://10.2.35.3:8080/24,391ba591c5",
"width": 1280,
"height": 853,
"format": "jpeg",
"thumbnail": "http://10.2.35.3:8080/21,3a0c5bae9a",
"credit": null,
"media_path": "api.demo/leaks-campaigns/my-first-campaign/jondoe/marked.jpeg",
"media_url": "https://imatag.com/api/v3/media/api.demo/leaks-campaigns/my-first-campaign/jondoe/marked.jpeg",
"metadata": {
"user.campaign": "my-first-campaign",
"user.recipient": "jondoe"
}
}
}
]
}
Request content
Parameter | Description |
---|---|
file | the URL of the query image (from the upload response) |
mode | leaks |
Response content
As a response, you will get a search object.