API documentation

The Everypixel API offers image recognition as a service.
The API is built around a simple idea. You send inputs (an image)
to the service and it returns predictions.
Get your free API key →

Authentication

After being signed up you will get credentials for API access. You must keep them safe. These credentials should be used for OAuth 2.0 authentication protocol. At the first step you should get the access token:

curl -X POST --data "client_id=<your-client-id>&client_secret=<your-client-secret>&grant_type=client_credentials" "https://api.everypixel.com/oauth/token"
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2 import BackendApplicationClient

client_id = '<your-client-id>'
client_secret = '<your-client-secret>'

oauth = OAuth2Session(client=BackendApplicationClient(client_id))
token = oauth.fetch_token(token_url='https://api.everypixel.com/oauth/token', auth=(client_id, client_secret))
$client_id = "<your-client-id>";
$secret = "<your-client-secret>";
$url = "https://api.everypixel.com/oauth/token";

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, "client_id=$client_id&client_secret=$secret&grant_type=client_credentials");
$data = curl_exec($curl);
curl_close($curl);

$json = json_decode($data);

You will get the json document containing access token with 1 hour lifetime. You can use only one access token at once.

{"access_token": "Aa4k7ink5cUXsG3V0OLDqNA3VF0BPg", "token_type": "Bearer", "scope": "keywording"}

Versioning

The versioning of API is a part of URI. To use v1 of the API the request URI should begin with /v1 followed by API method.

https://api.everypixel.com/v1

API methods

/keywords

By sending an image to this method you can get a list of suggested keywords. You may specify a number of returned words or a threshold of its minimum score. Just provide num_keywords or threshold parameter to this method.

Image should be specified by its url or uploaded with multipart form by parameter 'data'. You should use, respectively, GET and POST methods.

curl -H "Authorization: Bearer <access-token>" "https://api.everypixel.com/v1/keywords?url=http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg&num_keywords=10"
api = OAuth2Session(client_id, token=token)
params = {'url': 'http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg', 'num_keywords': 10}
keywords = api.get('https://api.everypixel.com/v1/keywords', params=params).json()

with open('image.jpg','rb') as image:
  data = {'data': image}
  keywords = api.post('https://api.everypixel.com/v1/keywords', files=data).json()
$authorization = "Authorization: Bearer <access-token>";
$url = "https://api.everypixel.com/v1/keywords?url=http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg&num_keywords=10";

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array($authorization));
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curl);
curl_close($curl);

$json = json_decode($data);
And the answer would be:
{
  "keywords": [
    {"keyword": "Domestic Cat", "score": 0.98873621225357056},
    {"keyword": "Pets", "score": 0.97396981716156006},
    {"keyword": "Animal", "score": 0.94135761260986328},
    {"keyword": "Cute", "score": 0.86750519275665283},
    {"keyword": "Kitten", "score": 0.83549922704696655},
    {"keyword": "Feline", "score": 0.74918556213378906},
    {"keyword": "Domestic Animals", "score": 0.71088212728500366},
    {"keyword": "Young Animal", "score": 0.703544020652771},
    {"keyword": "Mammal", "score": 0.67086690664291382},
    {"keyword": "Fur", "score": 0.61061191558837891}
  ],
  "status": "ok"
}

/quality

This method allows you to get the quality score for your photo. This service doesn't measure how cool or beautiful a person or an object on a photo may look. It cares only about technical parts like brightness, contrast, noise and so on. The service is not dedicated for scoring historical photos, illustrations or 3D visualizations.

Image should be specified by its url or uploaded with multipart form by parameter 'data'. You should use, respectively, GET and POST methods.

curl -H "Authorization: Bearer <access-token>" "https://api.everypixel.com/v1/quality?url=http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg"
api = OAuth2Session(client_id, token=token)
params = {'url': 'http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg'}
quality = api.get('https://api.everypixel.com/v1/quality', params=params).json()

with open('image.jpg','rb') as image:
    data = {'data': image}
    quality = api.post('https://api.everypixel.com/v1/quality', files=data).json()
$authorization = "Authorization: Bearer <access-token>";
$url = "https://api.everypixel.com/v1/quality?url=http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg";

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array($authorization));
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curl);
curl_close($curl);

$json = json_decode($data);
And the answer would be:
{
  "quality": {
    "score": 0.9729430521699124
  },
  "status": "ok"
}

/quality_ugc

The main difference between Stock photo scoring and this model is in the training dataset. User-Generated Photo Scoring is a model trained on a 347 000 of user photos from Instagram. Estimation parameters for this model were prepared by a group of 10 professional photographers. Scoring methods are based on five classes: very bad (0-20), bad (20-40), normal (40-60), good (60-80) and excellent (80-100).

This model is designed to evaluate user photos taken both by a professional camera and by a camera of a smartphone. It doesn't estimate the plot and do not measure how cool or beautiful a person or an object on a photo may look. It cares only about technical parts like brightness, contrast, noise and so on. The service is not dedicated for scoring historical photos, illustrations or 3D visualizations.

Image should be specified by its url or uploaded with multipart form by parameter 'data'. You should use, respectively, GET and POST methods.

curl -H "Authorization: Bearer <access-token>" "https://api.everypixel.com/v1/quality_ugc?url=http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg"
api = OAuth2Session(client_id, token=token)
params = {'url': 'http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg'}
quality = api.get('https://api.everypixel.com/v1/quality_ugc', params=params).json()

with open('image.jpg','rb') as image:
    data = {'data': image}
    quality = api.post('https://api.everypixel.com/v1/quality_ugc', files=data).json()
$authorization = "Authorization: Bearer <access-token>";
$url = "https://api.everypixel.com/v1/quality_ugc?url=http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg";

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array($authorization));
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curl);
curl_close($curl);

$json = json_decode($data);
And the answer would be:
{
  "quality": {
    "score": 0.5947988033294678,
    "class": 3
  },
  "status": "ok"
}

/video_keywords

By sending a video to this method you can get a list of suggested keywords. You may specify a number of returned words or a threshold of its minimum score. Just provide num_keywords or threshold parameter to this method.

The method successfully works only with video files with a duration of 5 to 60 seconds. Increasing the duration of the video decreases the relevance of keywords.

Video should be specified by its url or uploaded with multipart form by parameter 'data'. You should use, respectively, GET and POST methods.

curl -H "Authorization: Bearer <access-token>" "https://api.everypixel.com/v1/video_keywords?url=https://media.gettyimages.com/videos/man-talking-with-colleague-in-the-office-video-id843434746&num_keywords=10"
api = OAuth2Session(client_id, token=token)
params = {'url': 'https://media.gettyimages.com/videos/man-talking-with-colleague-in-the-office-video-id843434746', 'num_keywords': 10}
keywords = api.get('https://api.everypixel.com/v1/video_keywords', params=params).json()

with open('video.mp4','rb') as file:
  data = {'data': file}
  keywords = api.post('https://api.everypixel.com/v1/video_keywords', files=data).json()
$authorization = "Authorization: Bearer <access-token>";
$url = "https://api.everypixel.com/v1/video_keywords?url=https://media.gettyimages.com/videos/man-talking-with-colleague-in-the-office-video-id843434746&num_keywords=10";

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array($authorization));
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curl);
curl_close($curl);

$json = json_decode($data);
And the answer would be:
{
  "keywords": [
    {"keyword": "Medium shot", "score": 0.8536547422409058},
    {"keyword": "Real time", "score": 0.8485572934150696},
    {"keyword": "Animal", "score": 0.7466279963652293},
    {"keyword": "Men", "score": 0.86750519275665283},
    {"keyword": "Business", "score": 0.7157746723720005},
    {"keyword": "Indoors", "score": 0.6314120207514081},
    {"keyword": "Adult", "score": 0.6239697535832723},
    {"keyword": "People", "score": 0.6199291689055306},
    {"keyword": "Caucasian Ethnicity", "score": 0.6174033582210541},
    {"keyword": "Office", "score": 0.6139942705631256}
  ],
  "status": "ok"
}

/faces

This method allows you to find faces on your photo and estimate ages of them. The output is a list of estimated ages and bounding box coordinates of each face detected in the image. Also you will get confidence score of face recognition.

Image should be specified by its url or uploaded with multipart form by parameter 'data'. You should use, respectively, GET and POST methods.

curl -H "Authorization: Bearer <access-token>" "https://api.everypixel.com/v1/faces?url=https://labs.everypixel.com/static/i/estest_sample3.jpg"
api = OAuth2Session(client_id, token=token)
params = {'url': 'https://labs.everypixel.com/static/i/estest_sample3.jpg'}
quality = api.get('https://api.everypixel.com/v1/faces', params=params).json()

with open('image.jpg','rb') as image:
    data = {'data': image}
    quality = api.post('https://api.everypixel.com/v1/faces', files=data).json()
$authorization = "Authorization: Bearer <access-token>";
$url = "https://api.everypixel.com/v1/faces?url=https://labs.everypixel.com/static/i/estest_sample3.jpg";

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array($authorization));
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curl);
curl_close($curl);

$json = json_decode($data);
And the answer would be:
{
  "faces": [{
    "age": 20.553737561567686,
    "score": 0.9999862909317017,
    "bbox": [488.1020906694572, 147.58440036790006, 824.1707326180912, 581.0635042573758],
    "class": "Age - Young Adult"
  }],
  "status": "ok"
}

/lipsync

Lipsync API uses advanced machine learning algorithms and deep neural networks to synchronize lip movements with speech audio in videos.

This process results in high-quality, localized content that accurately reflects the speaker's expressions.

Sending a request to create
https://api.everypixel.com/v1/lipsync/create

client_id = '<your-client-id>'
client_secret = '<your-client-secret>'
audio_path = Path('folder/example.wav')
video_path = Path('folder/example.mp4')
audio_file = open(audio_path, 'rb')
video_file = open(video_path, 'rb')
      
response = requests.post(
    url= "https://api.everypixel.com/v1/lipsync/create",
    files={'audio': (audio_path.name, audio_file, "audio/wav"),
           'video': (video_path.name, video_file, "video/mp4")},
    data={
        "crop_percent": <35: int>,     # OPTIONAL, default=35
        "pads": <"0, 10, 0, 0": str>,  # OPTIONAL, default="0, 10, 0, 0"
        "use_gfpgan": <False: bool>,   # OPTIONAL, default=False
        "title": "<my_video: str>",    # OPTIONAL, default=task_id
        "callback": <url: str>         # OPTIONAL, default=None, see the callback section
    },
    auth=(client_id, client_secret)
)
audio_file.close()
video_file.close()
      
# Save task_id to check the status
task_id = response.json().get("task_id")
And the answer would be:
Status code: 201
{
  "task_id": "uuid",
  "status": "str",
  "progress": "float",
  "queue": "int",
  "result": "str"
}
Sending a request to check the status
https://api.everypixel.com/v1/lipsync/status?task_id={task_id}

There are 5 task statuses:
- PENDING: the task is in queue and yet to be started;
- STARTED: the task has started;
- SUCCESS: the task has successfully completed its execution;
- FAILURE: the task has failed when executed;
- REVOKED: the task has been terminated by user.

status = ""
while not status in ["SUCCESS", "FAILURE", "REVOKED"]:
    sleep(5)
    response = requests.get(
        url= "https://api.everypixel.com/v1/lipsync/status?task_id={task_id}"
    )
    print(response.status_code, response.json())
    status = response.json().get("status")
And the answer would be:
Status code: 200
{
  "task_id": "uuid",
  "status": "str",
  "progress": "float",
  "queue": "int",
  "result": "str"
}

/tts

Text-to-Speech is a powerful API that simplifies the process of converting text into speech and integrating it into a wide range of applications, including business, sales, customer support, and technical environments.


Sending a request to create
https://api.everypixel.com/v1/tts/create

client_id = '<your-client-id>'
client_secret = '<your-client-secret>'
response = requests.post(
    url="https://api.everypixel.com/v1/tts/create",
    data={"voice": "<voice: str>",
          "text": "<text to read: str>",
          "seed": <random seed > 0: int>,
          "title": "<my_audio: str>",
          "callback": "url"  # OPTIONAL, default=None, see the callback section
          },
    auth=(client_id, client_secret)
)
      
# Save task_id to check the status
task_id = response.json().get("task_id")
And the answer would be:
Status code: 201
{
  "task_id": "uuid",
  "status": "str",
  "eta": "float",
  "queue": "int",
  "result": "str"        
}
Sending a request to check the status
https://api.everypixel.com/v1/tts/status?task_id={task_id}

There are 5 task statuses:
- PENDING: the task is in queue and yet to be started;
- STARTED: the task has started;
- SUCCESS: the task has successfully completed its execution;
- FAILURE: the task has failed when executed;
- REVOKED: the task has been terminated by user;

status = ""
while not status in ["SUCCESS", "FAILURE", "REVOKED"]:
    sleep(5)
    response = requests.get(
        url="https://api.everypixel.com/v1/tts/status?task_id={task_id}"
    )
    print(response.status_code, response.json())
    status = response.json().get("status")
And the answer would be:
Status code: 200
{
  "task_id": "uuid",
  "status": "str",
  "eta": "float",
  "queue": "int",
  "result": "str"        
}          

/imageswap

Image Face Swap API — Effortlessly replace faces in photos with our versatile API. Create amusing or transformative visuals with ease, enhancing your image editing capabilities.


Sending a request to create
https://api.everypixel.com/v1/imageswap/create

client_id = '<your-client-id>'
client_secret = '<your-client-secret>'
source_path = Path('folder/source.png')
target_path = Path('folder/target.png')
source_file = open(source_path, 'rb')
target_file = open(target_path, 'rb')

response = requests.post(
    url= "https://api.everypixel.com/v1/imageswap/create",
    files={'source': (source_path.name, source_file, "image/png"),
           'target': (target_path.name, target_file, "image/png")},
    data={
        "use_gfpgan": <False: bool>,
        "title": "<title: str>",
        "callback": "<url: str>"  # OPTIONAL, default=None, see the callback section
    },
    auth=(client_id, client_secret)
)
source_file.close()
target_file.close()


# Save task_id to check the status
task_id = response.json().get("task_id")
And the answer would be:
Status code: 201
{
  "task_id": "uuid",
  "status": "str",
  "eta": "float",
  "queue": "int",
  "result": "str"
}
Sending a request to check the status
https://api.everypixel.com/v1/imageswap/status?task_id={task_id}

There are 5 task statuses:
- PENDING: the task is in queue and yet to be started;
- STARTED: the task has started;
- SUCCESS: the task has successfully completed its execution;
- FAILURE: the task has failed when executed;
- REVOKED: the task has been terminated by user;

status = ""
while not status in ["SUCCESS", "FAILURE", "REVOKED"]:
    sleep(5)
    response = requests.get(
        url=f"https://api.everypixel.com/v1/imageswap/status?task_id={task_id}"
    )
    print(response.status_code, response.json())
    status = response.json().get("status")
And the answer would be:
Status code: 200
{
  "task_id": "uuid",
  "status": "str",
  "eta": "float",
  "queue": "int",
  "result": "str"
}

/videoswap

Video Face Swap API — Revolutionize video content by seamlessly swapping faces using our API. Unleash creativity as you effortlessly exchange faces in videos for captivating results.


Sending a request to create
https://api.everypixel.com/v1/videoswap/create

client_id = '<your-client-id>'
client_secret = '<your-client-secret>'
source_path = Path('folder/source.png')
target_path = Path('folder/target.mp4')
source_file = open(source_path, 'rb')
target_file = open(target_path, 'rb')

response = requests.post(
    url= "https://api.everypixel.com/v1/videoswap/create",
    files={'source': (source_path.name, source_file, "image/png"),
           'target': (target_path.name, target_file, "image/png")},
    data={
        "use_gfpgan": <use_gfpgan: bool>,
        "title": "<title: str>",
        "callback": "<url: str>"  # OPTIONAL, default=None, see the callback section
    },
    auth=(client_id, client_secret)
)
source_file.close()
target_file.close()


# Save task_id to check the status
task_id = response.json().get("task_id")
And the answer would be:
Status code: 201
{
  "task_id": "uuid",
  "status": "str",
  "eta": "float",
  "queue": "int",
  "result": "str"
}
Sending a request to check the status
https://api.everypixel.com/v1/videoswap/status?task_id={task_id}

There are 5 task statuses:
- PENDING: the task is in queue and yet to be started;
- STARTED: the task has started;
- SUCCESS: the task has successfully completed its execution;
- FAILURE: the task has failed when executed;
- REVOKED: the task has been terminated by user;

status = ""
while not status in ["SUCCESS", "FAILURE", "REVOKED"]:
    sleep(5)
    response = requests.get(
        url=f"https://api.everypixel.com/v1/videoswap/status?task_id={task_id}"
    )
    print(response.status_code, response.json())
    status = response.json().get("status")
And the answer would be:
Status code: 200
{
  "task_id": "uuid",
  "status": "str",
  "eta": "float",
  "queue": "int",
  "result": "str"
}

Callbacks

When using Text-to-Speech, Lipsync, Imageswap and Videoswap API's, you can pass a URL of an endpoint on your machine as a callback parameter, expecting to receive a POST request with a JSON data containing status of the task and file url.

Make sure the specified endpoint is accessible from the internet.

{
    "task_id": "<uuid: str>",
    "status": "<status: str>",
    "file_url": "<url: str>",  # OPTIONAL, when status is SUCCESS
    "video_duration": <20: int>,  # OPTIONAL, in seconds, when the output file type is video
  }

Errors

Most of the errors returned by the API have json formatted text.

{
  "status": "error",
  "message": "Threshold must be float."
}

Also, you can receive non-successful HTTP status codes:
401 - you have no access to a specified endpoint. It might happen if your access token has been expired.
429 - you have exceeded available requests from your plan.