LABS
Documentation

Getting started

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.

Get your API key

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 →

Get trial

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:

  • New users: When you sign up for Everypixel Labs, you may be prompted to select a product or model to try. Choose the model you’re interested in to automatically start its free trial.
  • Existing users: If you already have an account, log in and go to the Explore Models section (or the models catalog) in your dashboard. Select the model you want to test, and click the option to Activate Trial for that model.

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.

Submit tasks via UI

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:

  • Using the Playground for most models: For all models except LipSync, Text-to-Speech (TTS), and Face Swap, the Playground lets you either upload an input file (image or video) or paste an URL to the file. After selecting or entering your input, click the Run button. The model will process the input just as it would via the API, and the output (result) will be displayed on the page, typically in a formatted JSON structure. This JSON response contains the same data you would get if you called the API directly.
  • Using the Playground for Lipsync, TTS, and Face Swap: These specific models produce output files (such as a generated video or audio). In the Playground interface for these models, you will be prompted to upload the required input files (for example, a video file and an audio track for LipSync, or an image for Face Swap, etc.). After uploading the inputs, click the Generate button. The system will process the task, and once ready, a downloadable output file (the synthesized video, audio, or image result) will be provided in the interface.

File availability

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.

Cost and usage accounting

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.

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.

Auto-payment

To make sure your balance is always topped up, you may want to consider enabling Auto-payment.

Why enable auto-payment

  1. Automatically top up your balance without manual intervention.
  2. Set a threshold, one-time payment amount, and monthly limits to suit your needs.
  3. As with manual balance top-ups, your payment details are kept secure, and you retain full control over your payments.

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.

  1. Navigate to the Balance menu in your account.
  2. Enter the following details in the Auto-payment block: Replenishment threshold: The balance amount at which auto-payment should be triggered. One-time payment: The amount to be automatically debited when the threshold is reached. Monthly limits: The maximum amount of auto-payments allowed per calendar month.
  3. Click on the Save and activate button. An email notification will confirm that Auto-payment has been activated.

How to turn auto-payment off

  1. Navigate to the Balance menu in your account.
  2. In the Auto-payment block click the Disable button. The button will revert to Save and activate, indicating that Auto-payment has been disabled.

How to update auto-payment details

  1. Navigate to the Balance menu in your account.
  2. In the Auto-payment block click the Disable button. The button will revert to Save and activate, indicating that Auto-payment has been disabled. This allows you to update your auto-payment details and then re-enable the option.
  3. Adjust the replenishment threshold, one-time payment and monthly limits as needed.
  4. Click Save and activate to apply the changes. You will receive an email notification confirming that Auto-payment has been activated.

Steps to take if an auto-payment fails

  1. Review your billing history in the Billing menu and auto-payment details in the Balance menu. Ensure your monthly limit has not been exceeded.
  2. Verify your payment method in the Billing menu. Make sure your payment method is on file, up to date and has sufficient funds.
  3. Check your billing info in the Billing menu. Ensure that your billing address is on file and current.

Privacy and responsible use of technology

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.

Authentication

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.

Where to find your API key

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.

How to use your API key

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:

  • cURL (command-line): Include the --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.
  • Using code libraries: In many programming languages or frameworks, you can set the basic authentication in a request. For example, in Python using the 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

Example request

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.

Versioning

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).

Request Methods (GET vs POST)

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:

  • GET requests: If you have a publicly accessible URL for the image or video, you can use a GET request and pass the URL as a query parameter (e.g. ?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.
  • POST requests: To upload a file directly, use a POST request with multipart form data. Each endpoint has a specific field name for the file (commonly this field is named 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.

Performance

Everypixel Labs imposes some rate limits and performance considerations to ensure reliable service.

Requests per second

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.

Concurrent processing

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.

Processing speed

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).

Image size

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.

Video length

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.

Checking status

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.

Input

To check the status of an asynchronous task, use the universal status endpoint. This endpoint is the same for all asynchronous tasks:

Endpoint:

  • GET /v1/status?task_id=<your_task_id>
  • or POST /v1/status with task_id in form data
    This request, like all others, requires authentication.

Response

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:
    • PENDING – The task is in queue, waiting to be processed.
    • STARTED – The task is being processed.
    • SUCCESS – The task has completed successfully; the result is available.
    • FAILURE – The task encountered an error and did not complete.
    • REVOKED – The task was canceled before completion.
  • 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.

Example

Request

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")

Result

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.

Image Keywording

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.

Processing speed

Processes images in under 1 second, handling up to 30 requests per second.

Optimization tips

The system automatically resizes images to 300×300 pixels before analysis. Uploading larger images won't improve accuracy but can slow down processing.

Input

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.
  • GET: Include the image URL in the url query parameter. Make sure the URL is properly encoded if it contains special characters (such as ? or &).
  • POST: Upload the image file with a multipart/form-data request. Use the field name data for the image file content.

Parameters

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.
    • Using 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.

Response

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).

Example

Request

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);

?>

Result

{
"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.)

Additional notes

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.

Video Keywording

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.

Processing speed

The time required depends on video length. Works best with 5–60 second clips, supporting 1 request per second.

Optimization tips

Longer videos may result in less relevant keywords since the AI has more content to analyze. If possible, keep clips concise.

Input

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.

  • GET: Include the video URL in the url query parameter. Make sure the URL is properly encoded if it contains special characters (such as ? or &).
  • POST: Upload the video file with a multipart/form-data request. Use the field name data for the image file content.

Parameters

  • 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).
    • Using 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.)

Response

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.

Example

Request

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);

Result

{
  "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.)

Image Captioning

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.

Processing speed

Processes images in under 1 second, handling up to 1 request per second.

Optimization tips

The system automatically resizes images to 300×300 pixels before analysis. Uploading larger images won't improve accuracy but can slow down processing.

Input

An image (JPEG or PNG).

  • GET: Include the image URL in the url query parameter. Make sure the URL is properly encoded if it contains special characters (such as ? or &).
  • POST: Upload the image file with a multipart/form-data request. Use the field name data for the image file content.

Parameters

  • 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.

Response

A JSON object with:

  • result – an object containing:
    • caption – The generated caption (string) for the image.
  • statustrue 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.”

Example

Request

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

{
  "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.

Age Recognition

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.

Processing speed

A highly computational task, handling up to 10 requests per second. Expect slightly longer processing times than standard image analysis.

Input

An image (JPEG or PNG) that may contain one or more human faces.

  • GET: Include the image URL in the url query parameter. Make sure the URL is properly encoded if it contains special characters (such as ? or &).
  • POST: Upload the image file with a multipart/form-data request. Use the field name data for the image file content.

Parameters

No additional parameters are required or supported for this endpoint besides the image itself.

Response

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).

Example

Request

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);

Result

{
  "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.

Stock Photo Quality

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.

Processing speed

Processes images in under 1 second, handling up to 30 requests per second.

Input

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.

  • GET: Include the image URL in the url query parameter. Make sure the URL is properly encoded if it contains special characters (such as ? or &).
  • POST: Upload the image file with a multipart/form-data request. Use the field name data for the image file content.

Parameters

No additional parameters are required or supported for this endpoint besides the image itself.

Response

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.

Example

Request

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);

Result

{
  "quality": {
    "score": 0.9729430521699124
  },
  "status": "ok"
}

(In this example, the image scored ~0.973 (97.3% quality), which indicates an excellent technical quality photograph.)

How to interpret the score

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.

UGC Photo Quality

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.

Processing speed

Processes images in under 1 second, handling up to 30 requests per second.

Input

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.

  • GET: Include the image URL in the url query parameter. Make sure the URL is properly encoded if it contains special characters (such as ? or &).
  • POST: Upload the image file with a multipart/form-data request. Use the field name data for the image file content.

Parameters

No additional parameters are required or supported for this endpoint besides the image itself.

Response

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:

  • Very Bad (0–20%) – Very low quality with significant technical issues.
  • Poor (20–40%) – Below average quality, with noticeable problems.
  • Normal (40–60%) – Acceptable, average quality. Meets basic standards but not outstanding.
  • Good (60–80%) – High quality, only minor imperfections if any.
  • Excellent (80–100%) – Top quality, technically almost perfect.

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).

Example

Request

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);

Result

{
  "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.

Lipsync

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 speed

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.

Input

You need to provide two inputs:

  • Audio – The new speech audio you want the person to appear to say. This should be a spoken word audio (preferably with no background music and minimal noise). The audio should ideally be a clean voice recording.
  • Supported audio formats: MP3, WAV, M4A, OGG, FLAC, OPUS, AIFF, WMA, WEBM, WEBA, OGA, MID, AU.
  • Video – The original video of the person (with a clear view of the person’s face and mouth for best results).
  • Supported video formats: MP4, MOV, AVI, WEBM, MPEG, MPG, M4V, WMV, OGV, OGM, ASX.

Both audio and video can be provided as URLs or uploaded as files:

  • GET: Use query parameter 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 &).
  • POST: Upload the input files directly. Use multipart form fields named audio (for the voice audio file) and video (for the original video file).

Parameters

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.

File requirements

  • Audio quality: Use clear voice recordings. Avoid music or heavy background noise in the audio. The model is not designed to handle singing or music.
  • Video quality: Use HD or higher resolution video where the speaker’s face is clearly visible.
  • Speaker visibility: The person’s mouth should be visible and not obstructed (no long occlusions or coverings).
  • Head movement: Videos where the speaker’s head is mostly facing the camera with minimal extreme angles work best. (A bit of movement is fine, but if the face rotates too far away, lip sync will be less accurate.)
  • Lighting: The face should be well-lit so the mouth region is clear.
  • Eye contact: Not directly required for lip sync, but videos without extreme eye squinting or facial distortion are ideal (as they often correlate with clear speech posture).

Response

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).

Example

Request

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")

Result

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.

Text-to-Speech

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).

Processing speed

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.

Input

  • GET: Use query parameters 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 &).
  • POST: Send form data with fields: text and voice (required), title and callback (optional).

Parameters

  • 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.

Response

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.

Example

Request

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")

Result

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.

Voices

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.

Result

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.

Image Face Swap

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.

Processing speed

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.

Optimization tips

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:

  • Head shape: For best results, the double should have a similar head shape to the donor. Consider factors such as cheekbones, chin, brow ridges, and forehead height.
  • Hairstyle: Hair and hairstyles are not transferred.
  • Close-ups: In close-ups (where the face takes up more than 1/6 of the frame), more time is needed to detail features such as wrinkles and facial expressions. If the face is too small, it is harder for the neural network to recognize the contour of the face.
  • Objects and accessories: The face should not be obstructed by objects. Glasses, beards, and other accessories can affect the results.
  • Color matching: The skin tones of the donor and the double should match closely to avoid unnatural color differences in the final result.

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.

Input

Two images are needed:

  • One image of the person whose face you want to transplant (source).
  • One image of the target person or scene where the face will be placed (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).

Parameters

  • 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.

Response

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).

Example

Request

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")

Result

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.

Video Face Swap

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.).

Processing speed

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.

Input

Two files are needed:

  • One face image — this is the face that will be inserted into the video (source).
    Supported formats: JPG, JPEG, PNG, WEBP, GIF, SVG, BMP, TIFF, TIF, AVIF, ICO, JFIF, PJPEG, APNG, SVGZ, PIP, XBM.
  • One target video — this is the video where the face will appear (target).
    Supported formats: MP4, MOV, AVI, WEBM, MPEG, MPG, M4V, WMV, OGV, OGM, ASX.

Both image and video can be provided as URLs or uploaded as files:

  • GET: Use query parameters 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 &).
  • POST: Upload two files using multipart form data:
    • source – the source image file (the “donor” face).
    • target – the target video file (the “double”) that will receive the new face.

Optimization tips

  • Head shape: For best results, the double should have a similar head shape to the donor. Consider factors such as cheekbones, chin, brow ridges, and forehead height.
  • Hairstyle: Hair and hairstyles are not transplanted.
  • Head turning: If the double turns his or her head too much, the neural network may not be able to recognize the face and the image may not be processed.
  • Close-ups: In close-up shots (where the face takes up more than 1/6 of the frame), more time is needed to detail features such as wrinkles and facial expressions. If the face is too small, it is harder for the neural network to recognize the face's contour.
  • Video resolution: At very high resolutions (such as 4K), the face may appear blurred due to technical limitations.
  • Objects and accessories: The face should not be obstructed by objects. Glasses, beards, and other accessories can affect the results.
  • Color matching: The skin tones of the donor and the double should match closely to avoid unnatural color differences in the final result.

Parameters

  • 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.

Response

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).

Example

Request

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")

Result

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.

Output considerations

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:

  • If the target video’s person moves a lot, or turns their head significantly away from the camera, the face swap might be less accurate during those frames.
  • The output video will generally retain the original video’s resolution and format (with the face modified).
  • Because this is effectively doing an image swap on every frame, processing time can be significant, and very long videos can take a long time or might be impractical to process in one go (the service might also have its own length limits, e.g., processing time or video duration per task – common usage from the pricing info was around 60 seconds as a chunk).

Use this API for relatively short videos to ensure timely processing and manageable output sizes.

Callbacks

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.

How to use

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.

Callback JSON payload example

{
  "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.

Security tips

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.

Error Handling

Everypixel Labs API uses standard HTTP status codes to indicate success or error, and provides error details in the response body when possible.

JSON error response

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:

  • 400 Bad Request – The request was invalid. This could be due to missing required parameters, invalid values (e.g., a string where a number was expected), malformed JSON, etc. The response body’s message will usually tell you what was wrong (like the example above).
  • 401 Unauthorized – Your credentials are missing or incorrect, or your access token (if using OAuth) is expired. This means the API did not accept your Client ID/Secret for the endpoint. Check that you’re sending them correctly and that your account is active.
  • 429 Too Many Requests – You have exceeded your usage quota (the number of requests allowed by your plan or the free trial limits). This is a rate-limit or quota issue on a longer time scale (not per second, but per day/month or overall usage). If you receive this, you’ll need to upgrade your plan or wait for the limit to reset. It indicates you’ve used up the allotted number of calls for the current billing period or trial.
  • 502 Bad Gateway – You sent too many requests too quickly (more than the allowed requests per second, as discussed in Rate Limits). The server could not handle the spike. You should slow down your request rate if you see this. Also can happen if a backend service is temporarily down.
  • 500 Internal Server Error – Something went wrong on Everypixel’s side. This is rare; it could indicate an outage or unexpected error in their system. These are not caused by your request, but by something internal. If they persist, you might need to contact support.

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).

Tips for error handling

  • Always check the HTTP status code first. If it’s not in the 200 range (success), handle it as an error.
  • If an error JSON is returned, log or display the message – it often guides you to the problem (e.g., “Image URL is missing” or “Unsupported file format”).
  • Implement retry logic for transient issues like 502 or 500, but with an appropriate backoff.
  • For 401, refresh your credentials (or get a new OAuth token) and try again.
  • For 429, you should stop making requests or slow down. This indicates you’ve hit a hard limit (short-term or long-term). Check your usage or upgrade your plan.