Everypixel Labs offers a range of advanced AI-powered services.
Our services are built around a simple idea: you provide input data (an image, video, audio, or text) to a service and it returns predictions or modifies the data. This documentation covers all available API endpoints, how to authenticate and use them, and what to expect in the responses. All API responses are in JSON format for easy integration.
If you have any questions or need assistance, please contact Everypixel Labs support at api@everypixel.com.
To use the Everypixel Labs API, you will need a set of API credentials. After registering for a free account on Everypixel Labs and logging in, navigate to your account’s API Keys section to create or obtain your API key pair. Each API key consists of two parts: a Client ID and a Secret Key. You can use the same API key pair with any of the Everypixel Labs API models – keys are not tied to a specific model. By default, you can create up to four (4) separate API key pairs in your account. This allows you to have multiple keys for different projects or to rotate keys if needed.
Get the API key →Everypixel Labs provides a free trial for each model so you can test its capabilities without immediate cost. Each API model comes with a free usage quota (trial). For example, a model might allow a certain number of free requests (e.g., 500 requests) or a certain amount of content (such as minutes of video/audio) to be processed at no charge. To activate a trial for a model, you have a couple of options:
Once a model’s trial is activated, you can make API calls to that model up to the free limit without incurring charges. The free trial usage applies whether you call the API via code or use the web interface. Note: The free trial for each model is a one-time offer – once you’ve used up the allotted free requests (or the trial period ends), further usage of that model will be billed according to the standard pricing for Everypixel Labs services (see the Everypixel Labs Pricing page for details). After the trial, you can continue using the model on a pay-as-you-go basis as outlined in the pricing plans.
Everypixel Labs provides a web-based Playground in your account dashboard that allows you to test API models through a graphical interface. This is a convenient way to try out the API without writing any code:
When you generate results through the UI (e.g., a lip-synced video or a swapped-face image), the output files are stored on the server for a limited time (currently, up to 24 hours). After 24 hours, these files are automatically deleted. If you want to keep the result, make sure to download the file to your device within that time window.
Running tasks via the web UI Playground uses the same API under the hood. This means that any requests you execute in the Playground will count against your free trial quota or your paid usage. In other words, the Playground is not “free” beyond what the API itself offers – it’s simply a different way to access the API. Once you exceed a model’s free trial limits, requests made through the UI will incur charges just like calls made programmatically. The cost of these requests follows the standard Everypixel Labs pricing (see the Pricing page for details), so you’ll want to top up your balance or have a payment method ready if you plan to continue heavy testing through the UI after the trial.
Note: If your API request results in an error (e.g., invalid input, authentication failure, etc.), it will not be counted toward your usage or billed. Only successful or accepted (queued) tasks are subject to billing.
After registering your account, you will have free limits to test our algorithm. Each algorithm has its own limits.
Limits will not be renewed once used. This applies to both API access and the use of algorithms through the Everypixel Labs interface. Once the free limit is exceeded, any additional usage will require payment. To continue using Everypixel Labs algorithms, simply top up your balance through the Balance menu in your account by clicking the Top up balance button.
If your balance is low, we will send a warning email. You can determine the minimum balance limit in your profile on the Balance page to let us know when to send you a warning.
After exceeding the number of available requests from your plan, you will see error 429.
To make sure your balance is always topped up, you may want to consider enabling Auto-payment.
Why enable auto-payment
How to set up auto-payment
Before setting up, make sure you have a Payment method and Billing info on file. To fill in these details, go to the right menu and select Billing.
How to turn auto-payment off
How to update auto-payment details
Steps to take if an auto-payment fails
We maintain the highest security standards to protect your information. For real-time API requests without a queue, we do not store your images and files. For queued requests, we delete input data within 24 hours.
At Everypixel, we are also committed to providing AI algorithms that empower professionals and make their work more effective and easier. We do not allow our AI technology to be used for criminal or unethical purposes.
To use our API, you must first register for an account on Everypixel Labs. Once registered and logged in, navigate to the API Keys section of your account to obtain your Client ID and Client Secret. These credentials are used to authenticate your API requests so that only you can use your account’s access.
All API calls require authentication using Basic HTTP authentication. This means you provide your Client ID and Client Secret with each request (for example, via an Authorization
header or using your HTTP client’s basic auth mechanism). In cURL, for instance, you can include --user "CLIENT_ID:CLIENT_SECRET"
in the command. In our code examples below, we use libraries that accept credentials as a tuple (client_id, client_secret)
.
Keep your Client ID and Secret safe. Do not expose them in public client-side code or share them, as they grant access to your account’s API usage.
Your API keys are located in the API Keys section of your Everypixel Labs account dashboard. In the web interface, click on your profile or account menu and select API Keys. On that page, you will see a list of your API key pairs. Each entry shows a Client ID (an identifier for the key) and a Secret Key (the password or secret associated with that ID). You can copy these values using the provided “copy” button or by selecting the text. Keep your Client ID and Secret Key safe – do not share them publicly or expose them in client-side code, since they grant access to your account’s API usage.
All API calls to Everypixel Labs must be authenticated using your API key. Everypixel supports HTTP Basic Authentication for API requests. This means you should provide your Client ID and Secret Key with each request. Most HTTP clients and libraries make this easy:
--user
option with your Client ID and Secret, separated by a colon. For example:
curl --user "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" "<API URL and parameters>"
This sends the Client ID and Secret as the HTTP Basic auth credentials.
requests
library, you can pass an auth
parameter with a tuple of your (client_id
, client_secret
). In JavaScript or other environments, you might set an Authorization
header with the Basic auth token. Every code example in this documentation includes the credentials as part of the request (either via an auth
parameter or equivalent).When using Basic Auth, your Client ID and Secret Key are transmitted securely (the connection is over HTTPS). Always ensure you’re making requests to the HTTPS endpoint. If you prefer a token-based approach, Everypixel Labs also supports OAuth 2.0 for authentication. Using OAuth, you would first obtain an access token (using your Client ID/Secret in an OAuth flow) and then use that token for API calls. OAuth can provide enhanced security for client-side applications (so you don’t directly embed your secret), but detailing the OAuth process is beyond the scope of this documentation. For getting started, using your Client ID and Secret via Basic Auth is the simplest method
To illustrate a basic API call with authentication, below is an example using cURL. This request calls the Image Keywording endpoint with a sample image URL, asking for keywords describing the image. Replace YOUR_CLIENT_ID
and YOUR_CLIENT_SECRET
with your actual credentials, and provide the URL of an image you want to analyze:
curl --user "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" "https://api.everypixel.com/v1/keywords?url=https://example.com/your_image.jpg"
In this example, the --user
flag supplies the API key (Client ID and Secret) for authentication. The request is a GET call to the /v1/keywords
endpoint with an url
parameter pointing to an image. The API will respond with a JSON object containing the analysis results (in this case, a set of keywords describing the image, along with their scores and other details). A successful response will have a structure like:
{
"status": "ok",
"keywords": [
{ "keyword": "tree", "score": 0.987 },
{ "keyword": "sky", "score": 0.932 },
...
]
}
This indicates the call was authenticated and processed successfully. (If your credentials were incorrect, you would receive a 401 Unauthorized
error, and if you exceeded your trial or quota, a 429 Too Many Requests
error, etc.)
Now that you have your API keys and understand how to authenticate requests (and have possibly tried out the trial and Playground), you are ready to start using the Everypixel Labs API in your application.
The base URL for the Everypixel Labs API is: https://api.everypixel.com/v1
The API is versioned, and the version number (e.g., v1
) is included as part of the URL path for each endpoint. All examples in this documentation use version 1 of the API. Ensure that you include the correct version prefix in your requests (for example, /v1/keywords
for the keywords endpoint).
All endpoints return data in JSON format. A typical successful response will include a field like "status": "ok"
(or a boolean true
in some cases) to indicate success. In case of errors, the response will include "status": "error"
and a message (details on errors are provided later in this document).
Many endpoints allow you to submit input data (images or videos) either by URL or by uploading the file. There are two ways to send data:
?url=<IMAGE_URL>
). Note: If the media URL contains special characters (such as &
or ?
), you must URL-encode the URL so that it is safely included as a parameter. For example, &
becomes %26
and ?
becomes %3F
. Failing to encode may result in an error or the URL being cut off.data
for image uploads, but some endpoints use a different name as noted below). In our examples, we show using Python’s requests
library and cURL for file uploads.When using POST to upload files, you do not need to URL-encode anything. Simply ensure you use the correct field name and include the binary file in the request.
Everypixel Labs imposes some rate limits and performance considerations to ensure reliable service.
You can send up to 30 requests per second simultaneously for most endpoints (such as Image Keywording, quality scoring, etc.). The Age Recognition endpoint is more compute-intensive and allows up to 10 requests per second. If you exceed these rates, the API will return an HTTP 502 Bad Gateway error indicating too many simultaneous requests. Make sure to throttle your requests or queue them on your side if you approach these limits.
For certain heavy operations that produce large outputs (like video processing or lengthy audio synthesis), the processing is handled sequentially for each task. For example, in Text-to-Speech and Lipsync, the tasks are processed one at a time per account – if you submit multiple jobs at once, they will be queued and executed sequentially. This ensures stable performance for each task.
The time it takes to get a result may vary by algorithm:
Image-based analysis (keywording, quality, face detection, captioning) is typically fast (near real-time, usually under a second or a few seconds per image), especially if images are not too large (see image size recommendations).
Text-to-Speech and LipSync: These involve generating or modifying media and require time. Audio is handled in real-time or faster, typically taking 1 minute to process 1 minute of audio or less. Processing 1 minute of video content may take approximately 10 minutes.
Video Face Swap: Similarly to LipSync, swapping a face in a video is computationally heavy and will take time roughly proportional to the video length (e.g., many times real-time).
Very large images can slow down the response without improving the outcome. The algorithms for image analysis automatically resize images to around 300×300 pixels internally to analyze them. This resolution is sufficient to maintain accuracy for recognition tasks. Providing an image much larger than that will not yield more tags or higher accuracy, it will only add processing time. It is recommended to resize or compress images to around 300 pixels on the shortest side before sending, to speed up the request.
For the Video Keywording endpoint, the recommended video duration is between 5 and 60 seconds. Videos longer than 60 seconds may result in less relevant keywords (as the content gets diluted over time). Very short videos (under 5 seconds) might not have enough content for meaningful analysis. There is also an upload size limit of 100 MB for video files on this endpoint.
Keep these considerations in mind to optimize your integration.
https://api.everypixel.com/v1/status
Some of the APIs (particularly media generation and transformation endpoints) operate asynchronously. Instead of returning the final result immediately, an asynchronous request will return a task ID (task_id
) that you can use to retrieve the result once processing is complete. This applies to endpoints like Text-to-Speech, Lipsync, Image and Video Face Swap, etc.
To check the status of an asynchronous task, use the universal status endpoint. This endpoint is the same for all asynchronous tasks:
Endpoint:
/v1/status?task_id=<your_task_id>
/v1/status
with task_id
in form data
The /v1/status
endpoint returns a JSON object with the following fields:
task_id
(string) – The unique ID of the task you are checking.status
(string) – The current status of the task. Possible values:
queue
(integer) – Position of your task in the processing queue. If queue = 0
, the task is either being processed or completed.result
(string or object) – The URL or data containing the output of the completed task. This will be populated only when status = SUCCESS
.This request also requires authentication (use the same credentials).
Python
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")
HTTP status 200:
{
"task_id": "uuid",
"status": "str",
"queue": "int",
"result": "str"
}
You can poll the /v1/status
endpoint periodically (e.g., every few seconds) until you receive a terminal status (SUCCESS
, FAILURE
, or REVOKED
). For a more efficient integration, consider using callbacks (see Callbacks section) to have the API notify you when the task is complete.
https://api.everypixel.com/v1/keywords
The Image Keywording API analyzes an image and returns a list of keywords (tags) describing the content of the image. The AI recognizes objects, people, places, colors and actions in the image and expresses them as descriptive keywords. This is useful for auto-tagging images, making them searchable, or adding metadata.
Processes images in under 1 second, handling up to 30 requests per second.
The system automatically resizes images to 300×300 pixels before analysis. Uploading larger images won't improve accuracy but can slow down processing.
url
query parameter. Make sure the URL is properly encoded if it contains special characters (such as ?
or &
).data
for the image file content.In addition to the image itself, the following query parameters are available to customize the keyword output:
num_keywords
(integer, optional) – The maximum number of keywords to return. The algorithm can return up to 50 keywords for an image, but will often determine the appropriate number of relevant keywords on its own. If you request more than 50, it will still cap the results at 50. If you don’t specify this parameter, a default number of keywords will be returned (typically around 10-15).threshold
(float, optional) – A confidence score threshold between 0.0 and 1.0. If provided, the API will only return keywords with a relevance score greater than or equal to this threshold. This can be used to filter out less confident tags.
num_keywords
and threshold
together: You may specify both. In that case, the algorithm will return up to num_keywords
results, but only those that meet the score threshold
. For example, if you request num_keywords=10
and threshold=0.5
, the service will return at most 10 keywords, but if only 7 keywords have scores ≥ 0.5, you will get those 7 (not 10).lang
(string, optional) – The language for the returned keywords. By default, keywords are returned in English ("en"
). You can request keywords in other supported languages by setting this parameter to one of: "en"
(English), "ru"
(Russian), "es"
(Spanish), "fr"
(French), "de"
(German), "pt"
(Portuguese), "it"
(Italian).colors
(boolean, optional) – If set to true
, the response will include a section with color-related keywords. These are basic color names describing the dominant colors in the image.num_colors
(integer, optional) – If colors=true
, this specifies how many color keywords to include (for example, the top 5 colors in the image). If not specified, a default number of colors will be returned when colors
is enabled.On success, the API responds with a JSON object containing a list of keywords (and optionally colors) identified in the image:
keywords
– An array of objects, each with:
keyword
– A keyword/tag (string) describing something in the image.score
– A confidence score (float value between 0 and 1) indicating how relevant or likely that keyword is for the image. Higher scores mean the keyword is more confidently associated with the image. The keywords are typically ordered from highest score to lowest.colors
– (Present only if colors=true
was requested). An array of color descriptions, each with:
name
– Name of the color (a common color name).rgb
– The RGB triplet values of that color.hex
– The hex code of the color.percentage
– The percentage of the image that this color occupies (an indication of dominance).status
– Status of the request. On success, this will be "ok"
(or a boolean true
in some cases). On error, it would be "error"
(with an accompanying message
– see the Errors section).
curl --user "<your-client-id>:<your-client-secret>" "https://api.everypixel.com/v1/keywords?url=http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg&num_keywords=10&colors=True&num_colors=5&lang=en"
import requests
client_id = '<your-client-id>'
client_secret = '<your-client-secret>'
params = {'url': 'http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg', 'num_keywords': 10, 'colors': True, 'num_colors': 5, 'lang': 'en'}
keywords = requests.get('https://api.everypixel.com/v1/keywords', params=params, auth=(client_id, client_secret)).json()
with open('image.jpg','rb') as image:
data = {'data': image}
keywords = requests.post('https://api.everypixel.com/v1/keywords', files=data, auth=(client_id, client_secret)).json()
print(keywords)
<?php
// Your client credentials
$client_id = '<your-client-id>';
$client_secret = '<your-client-secret>';
// The image URL and parameters
$params = [
'url' => 'http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg',
'num_keywords' => 10,
'colors' => true,
'num_colors' => 5,
'lang' => 'en'
];
// Build the query string from parameters
$query = http_build_query($params);
// The API endpoint
$url = "https://api.everypixel.com/v1/keywords?$query";
// Initialize a cURL session
$ch = curl_init($url);
// Set the basic authentication
curl_setopt($ch, CURLOPT_USERPWD, "$client_id:$client_secret");
// Set options to return the response as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Execute the request and fetch the response
$response = curl_exec($ch);
// Check for cURL errors
if (curl_errno($ch)) {
echo 'cURL error: ' . curl_error($ch);
exit;
}
// Close the cURL session
curl_close($ch);
// Decode the JSON response
$keywords = json_decode($response, true);
// Print the response (for debugging)
print_r($keywords);
?>
{
"keywords": [
{"keyword": "animal", "score": 0.9718916489849907},
{"keyword": "cute", "score": 0.9601239529000117},
{"keyword": "pets", "score": 0.949350643787409},
{"keyword": "kitten", "score": 0.9039852518100446},
{"keyword": "domestic cat", "score": 0.8818465735911328},
{"keyword": "domestic animals", "score": 0.773913246291121},
{"keyword": "young animal", "score": 0.6324827753197934},
{"keyword": "mammal", "score": 0.5434195324260841},
{"keyword": "feline", "score": 0.4977278418785077},
{"keyword": "small", "score": 0.46956064184549734}
],
"colors": [
{"name": "WhiteSmoke", "rgb": [237, 238, 240], "hex": "#edeef0", "percentage": 42.88},
{"name": "Sienna", "rgb": [123, 79, 50], "hex": "#7b4f32", "percentage": 7.43},
{"name": "Tan", "rgb": [195, 171, 146], "hex": "#c3ab92", "percentage": 16.71},
{"name": "Peru", "rgb": [168, 130, 96], "hex": "#a88260", "percentage": 15.34},
{"name": "PeachPuff", "rgb": [215, 207, 200], "hex": "#d7cfc8", "percentage": 17.64}
],
"status": "ok"
}
(The example above shows keywords and colors for an image of a kitten. The keywords
array provides tags like “animal”, “cute”, “kitten”, etc., each with a confidence score. The colors
array lists dominant colors such as WhiteSmoke and Sienna with their share in the image.)
The image keywording algorithm is trained mostly on real-world imagery. It may struggle to identify very abstract or fictional concepts (for example, fantasy or surreal images with objects that do not exist in reality). In such cases, it might return more general tags (e.g., “illustration”, “fantasy art”) rather than specific mythical creatures. However, if the image contains fantastical elements that resemble real objects, the algorithm can still tag those familiar elements.
https://api.everypixel.com/v1/video_keywords
The Video Keywording API works similarly to Image Keywording but for short video clips. It analyzes a video and returns a set of keywords describing the content (objects, scenes, actions) found across the video frames.
The time required depends on video length. Works best with 5–60 second clips, supporting 1 request per second.
Longer videos may result in less relevant keywords since the AI has more content to analyze. If possible, keep clips concise.
A video clip (recommended length between 5 and 60 seconds) provided by URL or file upload. Supported video formats include MP4, MPEG, MOV, and AVI. The maximum file size for upload is 100 MB. For best results, use a video between 5–60 seconds; longer videos can be processed but the relevance of the generated keywords may decrease as video length increases.
URL
in the url query parameter. Make sure the URL is properly encoded if it contains special characters (such as ?
or &
).name
data for the image file content.num_keywords
(integer, optional) – Maximum number of keywords to return (up to 50). If not provided, a default count of keywords will be returned.threshold
(float, optional) – Confidence threshold for keyword scores (0.0 to 1.0). Only keywords with a score ≥ threshold will be returned. You can combine threshold
with num_keywords
similarly to the image keywords endpoint (the same logic: it will stop early if the threshold condition limits the results).
num_keywords
and threshold
together: You may specify both. In that case, the algorithm will return up to num_keywords
results, but only those that meet the score threshold
. For example, if you request num_keywords=10
and threshold=0.5
, the service will return at most 10 keywords, but if only 7 (not 10).(This endpoint does not support the colors or lang parameters.)
On success, the API responds with a JSON object containing a list of keywords (and optionally colors) identified in the video:
keywords
– An array of objects, each with:
keyword
– A keyword/tag (string) describing something in the video.score
– A confidence score (float value between 0 and 1) indicating how relevant or likely that keyword is for the video. Higher scores mean the keyword is more confidently associated with the video. The keywords are typically ordered from highest score to lowest.status
– Status of the request. On success, this will be "ok"
(or a boolean true
in some cases). On error, it would be "error"
(with an accompanying message
– see the Errors section).Each keyword’s score
reflects how prominently or frequently that concept appeared in the video.
curl --user "<your-client-id>:<your-client-secret>" "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"
client_id = '<your-client-id>'
client_secret = '<your-client-secret>'
params = {'url': 'https://media.gettyimages.com/videos/man-talking-with-colleague-in-the-office-video-id843434746', 'num_keywords': 10}
keywords = requests.get('https://api.everypixel.com/v1/video_keywords', params=params, auth=(client_id, client_secret)).json()
with open('video.mp4','rb') as file:
data = {'data': file}
keywords = requests.post('https://api.everypixel.com/v1/video_keywords', files=data, auth=(client_id, client_secret)).json()
$authorization = "<your-client-id>" . ":" . "<your-client-secret>";
$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_USERPWD, $authorization);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curl);
curl_close($curl);
$json = json_decode($data);
{
"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"
}
(The above example suggests keywords for a video of people in an office setting, such as “Men”, “Business”, “Office”. Each keyword has an associated relevance score.)
https://api.everypixel.com/v1/image_captioning
The Image Captioning API generates a descriptive caption for an image. It uses AI to analyze the image and produce a human-readable sentence or phrase summarizing the scene. This is useful for automatically creating alt text, photo captions for social media or blog posts, or adding descriptions to images for accessibility.
Processes images in under 1 second, handling up to 1 request per second.
The system automatically resizes images to 300×300 pixels before analysis. Uploading larger images won't improve accuracy but can slow down processing.
An image (JPEG or PNG).
url
query parameter. Make sure the URL is properly encoded if it contains special characters (such as ?
or &
).data
for the image file content.caption_len
(string, optional) — controls the desired length of the generated caption:
"short"
– generates concise captions of approximately 3–6 words;"normal"
(default) – generates medium-length captions of approximately 7–12 words;"long"
– generates extended captions of approximately 13–20+ words.Note: Actual caption length may vary slightly depending on image complexity, but these ranges represent typical output for each setting.
A JSON object with:
result
– an object containing:
caption
– The generated caption (string) for the image.status
– true
on success (note: in this endpoint, the status
field is a boolean rather than the string "ok").Example: If you send in a picture of a small kitten sitting on a wooden floor, the API might return a caption like “a small cat sitting on the floor indoors.”
curl -X POST -u <your-client-id>:<your-client-secret> \ -F "data=@/path/to/image.jpg" \ https://api.everypixel.com/v1/image_captioning
client_id = '<your-client-id>'
client_secret = '<your-client-secret>'
with open('image.jpg','rb') as image:
data = {'data': image}
title = requests.post('https://api.everypixel.com/v1/image_captioning', files=data, auth=(client_id, client_secret)).json()
$authorization = "<your-client-id>" . ":" . "<your-client-secret>";
$url = "https://api.everypixel.com/v1/image_captioning";
$curl = curl_init();
curl_setopt($curl, CURLOPT_USERPWD, $authorization);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, ['data' => new CURLFile('/path/to/image.jpg')]);
$data = curl_exec($curl);
curl_close($curl);
$json = json_decode($data);
{
"result": {
"caption": "<caption>"
},
"status": True
}
Use this endpoint to quickly generate descriptions of images. It’s trained on a broad set of images and attempts to produce sensible captions, but it might occasionally be off if the image is unusual or very complex. Always review critical captions if accuracy is important.
https://api.everypixel.com/v1/faces
This AI model detects human faces in an image, and for each face, it estimates the person’s age. It also provides a confidence score for each detected face. This can be used for applications like demographic estimation or simple face detection in images.
A highly computational task, handling up to 10 requests per second. Expect slightly longer processing times than standard image analysis.
An image (JPEG or PNG) that may contain one or more human faces.
url
query parameter. Make sure the URL is properly encoded if it contains special characters (such as ?
or &
).data
for the image file content.No additional parameters are required or supported for this endpoint besides the image itself.
JSON object containing:
faces
– an array of detected faces. Each face in the array is an object with the following fields:
age
– The estimated age of the person in the image (as a floating-point number). This represents how old the person appears to the model.score
– The confidence score for the face detection (a float between 0 and 1). A score near 1 indicates the model is very confident a face was correctly detected and the age estimation is reliable.bbox
– The bounding box of the face in the image, given as an array [x_min, y_min, x_max, y_max]
coordinates. These coordinates indicate the region of the image where the face was found.class
– A string label categorizing the age range of the person. For example, it might return values like "Age - Young Adult"
, "Age - Child"
, etc., corresponding to the age estimate. In the example below, the class is "Young Adult" because the model estimated the age around 20.5 years.status
– "ok"
on success.If no face is detected in the image, the faces
array may be empty (and status
will still be "ok"
but essentially no face data to report).
curl --user "<your-client-id>:<your-client-secret>" "https://api.everypixel.com/v1/faces?url=https://labs.everypixel.com/static/i/estest_sample3.jpg"
client_id = '<your-client-id>'
client_secret = '<your-client-secret>'
params = {'url': 'https://labs.everypixel.com/static/i/estest_sample3.jpg'}
quality = requests.get('https://api.everypixel.com/v1/faces', params=params, auth=(client_id, client_secret)).json()
with open('image.jpg','rb') as image:
data = {'data': image}
quality = requests.post('https://api.everypixel.com/v1/faces', files=data, auth=(client_id, client_secret)).json()
$authorization = "<your-client-id>" . ":" . "<your-client-secret>";
$url = "https://api.everypixel.com/v1/faces?url=https://labs.everypixel.com/static/i/estest_sample3.jpg";
$curl = curl_init();
curl_setopt($curl, CURLOPT_USERPWD, $authorization);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curl);
curl_close($curl);
$json = json_decode($data);
{
"faces": [{
"age": 20.553737561567686,
"score": 0.9999862909317017,
"bbox": [488.1020906694572, 147.58440036790006, 824.1707326180912, 581.0635042573758],
"class": "Age - Young Adult"
}],
"status": "ok"
}
(In this example, one face was detected. The person’s estimated age is ~20.55 years old, with a very high confidence score of 0.99998. The bounding box coordinates locate the face in the image, and the class label indicates the age falls into the “Young Adult” category.)
This endpoint only provides an age estimate. It does not identify the person or give attributes like gender or emotion. The primary use is to get an approximate age and ensure a face is present. All images processed by this endpoint are not stored by Everypixel (see privacy note), so this won’t function as a face recognition (identity) service.
https://api.everypixel.com/v1/quality
This model evaluates the quality and market potential of professional photographs from the perspective of stock photography experts. It does not evaluate how attractive a person or object looks in the photo, but focuses solely on technical aspects such as brightness, contrast, and noise. The model is not intended to evaluate historical photos, illustrations or 3D visualizations.
Processes images in under 1 second
, handling up to 30 requests per second
.
An image to analyze, provided either by URL or by file upload. Supported image formats are JPEG and PNG. (Any image you provide will be internally resized for analysis as noted in the performance section.)
You can call this endpoint with an HTTP GET request if you have an image URL, or with a POST request to upload an image file.
url
query parameter. Make sure the URL is properly encoded if it contains special characters (such as ?
or &
).data
for the image file content.No additional parameters are required or supported for this endpoint besides the image itself.
A JSON object with:
quality
– An object containing:score
– A float between 0 and 1 representing the quality score. This can be interpreted as a percentage (e.g., 0.95 ~ 95% quality). A higher score means the photo is closer to meeting the high standards expected of stock photography (technically well-executed, properly exposed, etc.).status
– "ok"
on success.The quality score is a continuous value. You might decide to set your own threshold for what “acceptable” quality is depending on your application. For instance, you might consider anything above 0.8 as high quality.
curl --user "<your-client-id>:<your-client-secret>" "https://api.everypixel.com/v1/quality?url=http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg"
client_id = '<your-client-id>'
client_secret = '<your-client-secret>'
params = {'url': 'http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg'}
quality = requests.get('https://api.everypixel.com/v1/quality', params=params, auth=(client_id, client_secret)).json()
with open('image.jpg','rb') as image:
data = {'data': image}
quality = requests.post('https://api.everypixel.com/v1/quality', files=data, auth=(client_id, client_secret)).json()
$authorization = "<your-client-id>" . ":" . "<your-client-secret>";
$url = "https://api.everypixel.com/v1/quality?url=http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg";
$curl = curl_init();
curl_setopt($curl, CURLOPT_USERPWD, $authorization);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curl);
curl_close($curl);
$json = json_decode($data);
{
"quality": {
"score": 0.9729430521699124
},
"status": "ok"
}
(In this example, the image scored ~0.973 (97.3% quality), which indicates an excellent technical quality photograph.)
A high score means the photo meets many quality criteria (sharpness, exposure, etc.). However, a lower score doesn’t always mean the photo is “bad” – it might be technically fine but perhaps too generic, obviously staged, or otherwise not stock-worthy. For instance, an image might be perfectly sharp and well-exposed (technically perfect) but if it appears dated or overly posed, the model might give it a moderate score instead of a very high one. Use the score as a guideline for quality filtering or ranking.
https://api.everypixel.com/v1/quality_ugc
The main difference between Stock Photo Scoring and this model is the training dataset. User-generated photo scoring is a model trained on 347,000 user photos from Instagram. The estimation parameters for this model were created by a group of 10 professional photographers.
This model is designed to score user photos taken with both a professional camera and a smartphone camera. It doesn't evaluate the action and doesn't measure how cool or beautiful a person or object looks in a photo. It only cares about technical parts like brightness, contrast, noise, and so on. The service is not designed to rate historical photos, illustrations, or 3D visualizations.
Processes images in under 1 second
, handling up to 30 requests per second
.
An image to analyze, provided either by URL or by file upload. Supported image formats are JPEG
and PNG
. (Any image you provide will be internally resized for analysis as noted in the performance section.)
You can call this endpoint with an HTTP GET request if you have an image URL, or with a POST request to upload an image file.
url
query parameter. Make sure the URL is properly encoded if it contains special characters (such as ?
or &
).data
for the image file content.No additional parameters are required or supported for this endpoint besides the image itself.
JSON with:
quality
– an object containing:score
– float between 0 and 1, representing the quality score of the photo.class
– an integer from 1 to 5 indicating the quality category the photo falls into.status
– "ok"
on success.The class
value corresponds to five quality categories:
These class ranges are determined by the score percentage. The class
can be useful for quickly categorizing photos (for example, you might reject anything in class 1 or 2 if you require decent quality).
curl --user "<your-client-id>:<your-client-secret>" "https://api.everypixel.com/v1/quality_ugc?url=http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg"
client_id = '<your-client-id>'
client_secret = '<your-client-secret>'
params = {'url': 'http://image.everypixel.com/2014.12/67439828186edc79b9be81a4dedea8b03c09a12825b_b.jpg'}
quality = requests.get('https://api.everypixel.com/v1/quality_ugc', params=params, auth=(client_id, client_secret)).json()
with open('image.jpg','rb') as image:
data = {'data': image}
quality = requests.post('https://api.everypixel.com/v1/quality_ugc', files=data, auth=(client_id, client_secret)).json()
$authorization = "<your-client-id>" . ":" . "<your-client-secret>";
$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_USERPWD, $authorization);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curl);
curl_close($curl);
$json = json_decode($data);
{
"quality": {
"score": 0.5947988033294678,
"class": 3
},
"status": "ok"
}
(In this example, the photo scored ~0.595 (59.5%) which falls into class 3, “Normal” quality. It’s an average quality photo — not outstanding, but acceptable.)
Use the score
if you need a precise measure, or use the class for a quick categorization. For instance, you could label photos or filter them by these quality classes for users.
https://api.everypixel.com/v1/lipsync
By merging a video source and voiceover, this model accurately reproduces a person's lip movements in a video with speech in multiple languages. This is useful for creating localized videos, voice-overs, or fun applications where you replace what a person is saying in a video.
The model uses advanced machine learning to ensure the lip movements match the audio as naturally as possible, producing a high-quality result that reflects the speaker’s expressions.
Processing 1 minute of video can take significantly longer than real-time. Tasks are processed sequentially per account.
Note: This is an asynchronous operation. Once you create a task, it will be processed in the background. Depending on the input size and model type, generation may take some time. You can check the status manually or use a callback to be notified when the result is ready.
You need to provide two inputs:
Both audio and video can be provided as URLs or uploaded as files:
audio_url
and video_url
to point to the audio and video files accessible online. Make sure all values are URL-encoded if they contain special characters (such as ?
or &
).audio
(for the voice audio file) and video
(for the original video file).title
(string, optional): Sets the name for the output file; if omitted, a default name will be used.
callback
(URL, optional): If set, the API will POST the result to this URL when processing is complete — use instead of manual status polling.
model
(string, optional, default = "normal"
) — Defines which version of the model to use:
"normal"
: standard model offering the best available quality (default)."fast"
: lightweight version that responds faster but with reduced quality.On a successful request, returns HTTP status 201 and a JSON payload including:
task_id
– ID of the created lip sync task.status
– initial status (PENDING
or STARTED
).queue
– position in queue (if any).result
– will contain the output video URL once the task is finished (initially empty or placeholder).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')
# POST request
response = requests.post(
url="https://api.everypixel.com/v1/lipsync/create",
files={'audio': (audio_path.name, audio_file),
'video': (video_path.name, video_file)},
data={
"title": "<my_video: str>", # OPTIONAL, default=task_id, affects the file name
"callback": <url: str> # OPTIONAL, default=None, see the callback section
},
auth=(client_id, client_secret)
)
audio_file.close()
video_file.close()
# or GET request
response = requests.get(
url="https://api.everypixel.com/v1/lipsync/create",
params={
"audio_url": "https://labs.everypixel.com/media/tts/audio_samples_demo/ascend.mp3",
"video_url": "https://labs.everypixel.com/static/v/lipsync.mp4",
"title": "<my_video: str>" # OPTIONAL, default=task_id, affects the file name
"callback": <url: str> # OPTIONAL, default=None
},
auth=(client_id, client_secret)
)
# Save task_id to check the status
task_id = response.json().get("task_id")
Status code: 201
{
"task_id": "uuid",
"status": "str",
"progress": "float",
"queue": "int",
"result": "str"
}
Note: This is an asynchronous operation. Use the universal /v1/status
endpoint with your task ID to check progress. See the Checking Status section for details.
https://api.everypixel.com/v1/tts
https://api.everypixel.com/v1/tts/voices
This model makes it easy to convert text to speech and integrate it into business, sales, or customer support processes, as well as applications in a variety of technical environments. Everypixel’s TTS supports multiple languages and voices (including different accents or genders for some languages).
Converts 1 minute of text to speech in under 1 minute. Requests are processed sequentially, meaning multiple tasks will queue and execute one by one.
Note: This is an asynchronous operation. Once you create a task, it will be processed in the background. Depending on the input size and model type, generation may take some time. You can check the status manually or use a callback to be notified when the result is ready.
text
and voice
to pass the input directly in the URL. Optional parameters: title
, callback
. Make sure all values are URL-encoded if they contain special characters (such as ?
or &
).text
and voice
(required), title
and callback
(optional).voice
(string, required): The identifier of the voice to use (e.g., a name like "jack"). To view the full list of available voices, use the v1/tts/voices
endpoint — see the Voices section for details.text
(string, required): The text you want spoken aloud. This can be a short sentence, a paragraph, or multiple paragraphs.title
(string, optional): Sets the name for the output file; if omitted, a default name will be used.callback
(URL, optional): If set, the API will POST the result to this URL when processing is complete — use instead of manual status polling.Because this is a generation task, you will get a Task ID in response to your create request, rather than the audio content immediately. The audio file (typically in MP3 or WAV format) will be available via a URL when the task completes.
A successful create request will return HTTP status 201 Created and a JSON payload with at least:
task_id
– a unique identifier for the TTS task (you will use this to check status or identify the callback).status
– the current status of the task. Immediately after creation, this will usually be "PENDING"
(if queued) or "STARTED"
(if it began processing right away).queue
– an integer indicating your position in the queue or number of tasks ahead of yours. 0 or 1 typically means it’s being processed or about to start.result
– a placeholder (often an empty string or URL path) for where the result will be available. Before completion this may be empty or some default. Once the task is finished, this field will contain the URL of the generated audio file.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>",
"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")
Status code: 201
{
"task_id": "uuid",
"status": "str",
"eta": "float",
"queue": "int",
"result": "str"
}
Note: This is an asynchronous operation. Use the universal /v1/status
endpoint with your task ID to check progress. See the Checking Status section for details.
https://api.everypixel.com/v1/tts/voices
Returns a list of all supported TTS voices with metadata, including voice name, language, gender, and age group. This request is free and does not count toward your usage quota.
HTTP status 200:
{
"api_name": "jack",
"age": "adult",
"language": "eng",
"gender": "male"
}
api_name
– a unique identifier for the voice model. Use this value in the voice
parameter when making TTS.language
– the language this voice is trained for (e.g. eng
, spa
, fra
).gender
– the speaker’s gender. Values are male
or female
.age
– the approximate age group of the voice. Possible values include child
, young
, adult
, and old
.https://api.everypixel.com/v1/imageswap
The Image Face Swap API takes two images – one of a “donor” (source face) and one of a “double” (target image) – and transfers the face from the donor onto the double. It isn’t a simple copy-paste; the algorithm uses neural networks to simulate the donor’s face on the target image, aligning facial features and preserving expressions and lighting for a realistic result. This can be used for face replacement apps or creative editing where you want to see person A’s face on person B’s body.
Computationally intensive, processing one request at a time per account.
Note: This is an asynchronous operation. Once you create a task, it will be processed in the background. Depending on the input size and model type, generation may take some time. You can check the status manually or use a callback to be notified when the result is ready.
The better the match between the source and target images (pose, lighting, resolution), the faster and more natural the output. The AI tries to maintain realism by considering various factors:
By keeping these factors in mind (e.g., using images where the individuals have similar poses and lighting), you can achieve more realistic face swap outcomes.
Two images are needed:
source
).target
).Supported formats for both images: JPG, JPEG, PNG, WEBP, GIF, SVG, BMP, TIFF, TIF, AVIF, ICO, JFIF, PJPEG, APNG, SVGZ, PIP, XBM.
Both images can be provided as URLs or uploaded as files:
GET: Use query parameters source_url
and target_url
to pass image URLs directly in the request. Optional parameters: title
, callback
. Make sure all URLs are properly encoded if they contain special characters (such as ?
or &
).
POST: Upload two image files using multipart form data:
source
– the source image file (the “donor” face).target
– the target image file (the “double” to receive the face).use_gfpgan
(boolean, optional, default false
): If true
, enable an extra face enhancement step (using GFPGAN) after the swap. This can sometimes improve the visual quality of the result (sharpening or restoring facial details) at the cost of slightly longer processing.title
(string, optional): Sets the name for the output file; if omitted, a default name will be used.callback
(URL, optional): If set, the API will POST the result to this URL when processing is complete — use instead of manual status polling.On a successful request, returns HTTP status 201 and a JSON payload including:
task_id
– ID of the created face swap task.status
– initial status (PENDING
or STARTED
).queue
– position in queue (if any).result
– will be available as an image file (typically a URL to a JPG/PNG).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),
'target': (target_path.name, target_file)},
data={
"use_gfpgan": <False: bool>,
"title": "<title: str>", # OPTIONAL, default=task_id, affects the file name
"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")
Status code: 201
{
"task_id": "uuid",
"status": "str",
"eta": "float",
"queue": "int",
"result": "str"
}
Note: This is an asynchronous operation. Use the universal /v1/status
endpoint with your task ID to check progress. See the Checking Status section for details.
https://api.everypixel.com/v1/videoswap
The Video Face Swap API is the video counterpart to image face swap. It takes a single image of a person (the donor face) and a video (the target) and produces a new video where the donor’s face is superimposed onto the person in the target video throughout the video’s duration. Essentially, it applies face swapping to each frame of the video, creating the effect that the person in the video has been replaced with the person from the photo. This is a complex process since it has to maintain consistency across frames (accounting for movement, lighting changes, etc.).
A resource-heavy process. 1-minute videos take multiple times real-time to process. Requests are queued and handled sequentially per account.
Note: This is an asynchronous operation. Once you create a task, it will be processed in the background. Depending on the input size and model type, generation may take some time. You can check the status manually or use a callback to be notified when the result is ready.
Two files are needed:
source
).target
).Both image and video can be provided as URLs or uploaded as files:
source_url
(for the face image) and target_url
(for the target video) to pass file URLs directly in the request. Optional parameters: title
, callback
. Make sure all URLs are properly encoded if they contain special characters (such as ?
or &
).source
– the source image file (the “donor” face).target
– the target video file (the “double”) that will receive the new face.use_gfpgan
(boolean, optional, default false
): If true
, enable an extra face enhancement step (using GFPGAN) after the swap. This can sometimes improve the visual quality of the result (sharpening or restoring facial details) at the cost of slightly longer processing.title
(string, optional): Sets the name for the output file; if omitted, a default name will be used.callback
(URL, optional): If set, the API will POST the result to this URL when processing is complete — use instead of manual status polling.On a successful request, returns HTTP status 201 and a JSON payload including:
task_id
– ID of the created face swap task.status
– initial status (PENDING
or STARTED
).queue
– position in queue (if any).result
– will be available as a video file (typically a URL to a MP4/MPEG).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),
'target': (target_path.name, target_file)},
data={
"use_gfpgan": <False: bool>,
"title": "<title: str>", # OPTIONAL, default=task_id, affects the file name
"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")
Status code: 201
{
"task_id": "uuid",
"status": "str",
"eta": "float",
"queue": "int",
"result": "str"
}
Note: This is an asynchronous operation. Use the universal /v1/status
endpoint with your task ID to check progress. See the Checking Status section for details.
The output video will have the face from the source image in place of the original face for the entire duration. Keep in mind all the limitations mentioned for image face swaps also apply here, plus:
Use this API for relatively short videos to ensure timely processing and manageable output sizes.
For the asynchronous APIs (Text-to-Speech, Lipsync, Image Face Swap, Video Face Swap), instead of (or in addition to) polling the status, you can use callbacks to get notified when the task is complete. This is convenient to avoid continuous polling in your application.
When creating a task (for example, calling /v1/tts/create
or /v1/lipsync/create
), include a callback
parameter with a URL that your application can receive requests on. This URL should be publicly accessible (Everypixel’s servers will need to reach it over the internet).
When the task finishes (either successfully or with failure), the Everypixel API will send an HTTP POST request to your callback URL with a JSON body containing the status of the task and, if successful, the location of the output file.
{
"task_id": "",
"status": "",
"file_url": "", # OPTIONAL, when status is SUCCESS
"video_duration": <20: int>, # OPTIONAL, in seconds, when the output file type is video
}
task_id
– the ID of the task (so you know which request this corresponds to).status
– the final status of the task ("SUCCESS"
, "FAILURE"
, etc.).file_url
– if the task succeeded, this is the URL where the output (audio/video/image) can be downloaded. For tasks that produce an output file, you can use this URL to fetch the result.video_duration
– if the output is a video (Lipsync or Video Face Swap tasks), the callback may include the duration of the output video in seconds for your reference.Make sure your callback endpoint responds quickly and with a 200 status when it receives the POST, and that it is expecting the above JSON. You might, for example, update your database record for that task as completed and store the file_url
for later retrieval by your front-end or user.
If your callback URL is sensitive, you might want to include some token or secret in the URL that you can verify (since anyone who knows the URL could potentially hit it). For example, use a long unguessable path or require an API key as a query param in the callback URL – something that you check on your server to ensure the request truly came from Everypixel. The Everypixel callback doesn’t include an authentication header by itself; it just POSTs the JSON to the given URL.
Everypixel Labs API uses standard HTTP status codes to indicate success or error, and provides error details in the response body when possible.
If an error occurs and the API is able to return a response, it will typically be a JSON object containing:
status
: "error"
message
: A descriptive error message indicating what went wrong.Example of an error response (for instance, if you passed an invalid value for a parameter):
{
"status": "error",
"message": "Threshold must be float."
}
In addition, pay attention to the HTTP status code of the response:
For asynchronous tasks (TTS, Lipsync, Image and Video Face Swap), a "FAILURE"
status in the status check or callback is how the API indicates that something went wrong during processing. The status
field will be "FAILURE"
and typically a message
might be included to explain (though in some cases, you might only see failure and need to try again or contact support for specifics).
message
– it often guides you to the problem (e.g., “Image URL is missing” or “Unsupported file format”).