Using our Midjourney API with PHP
Overview
This guide assumes you're using a demo account (opens in a new tab). We'll quickly get started by generating an image and seeing the results. You get to pick which language you use as well.
The best part is that you can copy the code and use it right away!
The easiest to start generating Midjourney images via API is by getting a demo account (opens in a new tab).
Get the Authentication Token
- Once you buy a demo account (opens in a new tab), you will receive an email username and password. Use that to log into our demo server: https://cl.imagineapi.dev (opens in a new tab).
- After you log in, click your
user icon
on the bottom left: - These are you user settings. Scroll to the bottom and find the
Token
field andclick the round arrow button
to regenerate the token: - This will create a new token that you can use to authorize your API call with, so
copy the token
. You will be using this shortly so keep it around in a file somewhere.: - Then
click the checkbox button
on the top right to save your account changes:
That's all. Now we will use the token to authenticate our API calls.
Generating an image
Now that you have your authentication token, you can generate your first image.
<?php
$data = [
'prompt' => 'a pretty lady at the beach --ar 9:21 --chaos 40 --stylize 1000'
];
$url = 'https://cl.imagineapi.dev/items/images/';
$headers = [
"Authorization: Bearer u667iLDO2Xfu0-qpv_nu82EeeDtYGlsf", # <<<< TODO change the API key here
"Content-Type: application/json"
];
$options = [
'http' => [
'method' => 'POST',
'header' => join("\r\n", $headers),
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$responseData = json_decode($response, true);
echo json_encode($responseData, JSON_UNESCAPED_SLASHES) . "\n";
?>
We run it using (PHP7+ is required):
❯ php --version
PHP 8.2.10 (cli) (built: Aug 31 2023 18:52:55) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.10, Copyright (c) Zend Technologies
with Zend OPcache v8.2.10, Copyright (c), by Zend Technologies
❯ php midjourney-api.php
The output will look like this:
{
"data": {
"id": "0ecdd164-5920-4b58-9727-6347e8e74eea",
"prompt": "a pretty lady at the beach --ar 9:21 --chaos 40 --stylize 1000",
"results": null,
"user_created": "126353b1-2c3e-42af-9597-b141c0e50fae",
"date_created": "2023-09-18T18:38:05.077Z",
"status": "pending",
"progress": null,
"url": null,
"error": null,
"upscaled_urls": null,
"upscaled": [],
"ref": null
}
}
Now your prompt will be sent to Midjourney.
A few important details to note:
- The image
id
will remain the same and we can use it to get the data and status of it status
ispending
which is the default when an image generation is first created- when it's done generating (
status
will becompleted
),upscaled_urls
will have 4 separate image urls andurl
will have one grid image that has all four images in it
Let's continue below and get the images that got generated.
Getting the generated image
It will take up to 30 seconds for an image to get generated in the demo server. We're using a Midjourney account with turbo mode enable so it's usually quite fast.
Let's create a new file to get the image we created in the previous step.
<?php
$imageId = '0ecdd164-5920-4b58-9727-6347e8e74eea'; // TODO: change this
$url = 'https://cl.imagineapi.dev/items/images/' . $imageId;
$headers = [
'Authorization: Bearer u667iLDO2Xfu0-qpv_nu82EeeDtYGlsf', // TODO: remember to change this
];
$options = [
'http' => [
'method' => 'GET',
'header' => join("\r\n", $headers)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$responseData = json_decode($response, true);
echo json_encode($responseData, JSON_UNESCAPED_SLASHES) . "\n";
?>
We run it using (PHP7+ is required):
❯ php --version
PHP 8.2.10 (cli) (built: Aug 31 2023 18:52:55) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.10, Copyright (c) Zend Technologies
with Zend OPcache v8.2.10, Copyright (c), by Zend Technologies
❯ php get-image.php
And if the image finished generating, this is the results we get:
{
"data": {
"id": "0ecdd164-5920-4b58-9727-6347e8e74eea",
"prompt": "a pretty lady at the beach --ar 9:21 --chaos 40 --stylize 1000",
"results": "e7587d63-5b9b-4905-90c9-092fcf6f3f72",
"user_created": "126353b1-2c3e-42af-9597-b141c0e50fae",
"date_created": "2023-09-18T18:38:05.077Z",
"status": "completed",
"progress": null,
"url": "https://cl.imagineapi.dev/assets/e7587d63-5b9b-4905-90c9-092fcf6f3f72/e7587d63-5b9b-4905-90c9-092fcf6f3f72.png",
"error": null,
"upscaled_urls": [
"https://cl.imagineapi.dev/assets/3305f0ce-86fe-4891-9a39-6d17929a0f0a/3305f0ce-86fe-4891-9a39-6d17929a0f0a.png",
"https://cl.imagineapi.dev/assets/6fe0c304-4fa9-478b-a798-78ef2ed16f51/6fe0c304-4fa9-478b-a798-78ef2ed16f51.png",
"https://cl.imagineapi.dev/assets/0973622c-b8a2-49b8-b3eb-19535ee3f634/0973622c-b8a2-49b8-b3eb-19535ee3f634.png",
"https://cl.imagineapi.dev/assets/33148696-fc82-4cf6-8df8-462238f5494f/33148696-fc82-4cf6-8df8-462238f5494f.png"
],
"upscaled": [
"0973622c-b8a2-49b8-b3eb-19535ee3f634",
"3305f0ce-86fe-4891-9a39-6d17929a0f0a",
"33148696-fc82-4cf6-8df8-462238f5494f",
"6fe0c304-4fa9-478b-a798-78ef2ed16f51"
],
"ref": null
}
}
This is great but it would be nice to have the script automatically check the image and show us when it's done:
Waiting for the image automatically
Let's take the code snippet where the image is generated and make it check every 5 seconds to see if the image has been generated (i.e. status
is completed
or failed
):
<?php
$data = [
'prompt' => 'a pretty lady at the beach --ar 9:21 --chaos 40 --stylize 1000'
];
$url = 'https://cl.imagineapi.dev/items/images/';
$headers = [
"Authorization: Bearer u667iLDO2Xfu0-qpv_nu82EeeDtYGlsf", # <<<< TODO change the API key here
"Content-Type: application/json"
];
$options = [
'http' => [
'method' => 'POST',
'header' => join("\r\n", $headers),
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$responseData = json_decode($response, true);
// Initial response
echo json_encode($responseData, JSON_UNESCAPED_SLASHES) . "\n";
// Polling for completion
while (true) {
sleep(5); // Wait for 5 seconds
$imageId = $responseData['data']['id'];
$url = 'https://cl.imagineapi.dev/items/images/' . $imageId;
$options = [
'http' => [
'method' => 'GET',
'header' => join("\r\n", $headers),
]
];
$innerContext = stream_context_create($options);
$response = file_get_contents($url, false, $innerContext);
$checkData = json_decode($response, true);
if ($checkData['data']['status'] === 'completed' || $checkData['data']['status'] === 'failed') {
// Stop when the image is completed or failed
echo json_encode($checkData, JSON_UNESCAPED_SLASHES) . "\n";
break;
} else {
echo "Image is not finished generation. Status: " . $checkData['data']['status'] . "\n";
}
// TODO: add a check to ensure this does not run indefinitely
}
?>
Here's how the output might look like:
{
"data": {
"id": "858241f5-ff0c-42db-bb33-d7dec4e4ab1a",
"prompt": "a pretty lady at the beach --ar 9:21 --chaos 40 --stylize 1000",
"results": null,
"user_created": "126353b1-2c3e-42af-9597-b141c0e50fae",
"date_created": "2023-09-18T18:55:33.445Z",
"status": "pending",
"progress": null,
"url": null,
"error": null,
"upscaled_urls": null,
"upscaled": [],
"ref": null
}
}
Image is not finished generation. Status: pending
Image is not finished generation. Status: pending
Image is not finished generation. Status: pending
Image is not finished generation. Status: pending
Image is not finished generation. Status: in-progress
Image is not finished generation. Status: in-progress
Image is not finished generation. Status: in-progress
Image is not finished generation. Status: in-progress
Image is not finished generation. Status: in-progress
{
"data": {
"id": "858241f5-ff0c-42db-bb33-d7dec4e4ab1a",
"prompt": "a pretty lady at the beach --ar 9:21 --chaos 40 --stylize 1000",
"results": "9e8adf49-ab32-4af4-ab30-f960d6db724d",
"user_created": "126353b1-2c3e-42af-9597-b141c0e50fae",
"date_created": "2023-09-18T18:55:33.445Z",
"status": "completed",
"progress": null,
"url": "https://cl.imagineapi.dev/assets/9e8adf49-ab32-4af4-ab30-f960d6db724d/9e8adf49-ab32-4af4-ab30-f960d6db724d.png",
"error": null,
"upscaled_urls": [
"https://cl.imagineapi.dev/assets/00200514-7de4-4f4a-a621-7e8fb892146a/00200514-7de4-4f4a-a621-7e8fb892146a.png",
"https://cl.imagineapi.dev/assets/03b7bb1b-43ed-4e08-b7fe-67161be23417/03b7bb1b-43ed-4e08-b7fe-67161be23417.png",
"https://cl.imagineapi.dev/assets/f5fc3d1b-e5f3-4f9f-825a-1b70bb4ca014/f5fc3d1b-e5f3-4f9f-825a-1b70bb4ca014.png",
"https://cl.imagineapi.dev/assets/68c68076-cce8-4ea3-a5c8-15aaaa2ce3e6/68c68076-cce8-4ea3-a5c8-15aaaa2ce3e6.png"
],
"upscaled": [
"00200514-7de4-4f4a-a621-7e8fb892146a",
"03b7bb1b-43ed-4e08-b7fe-67161be23417",
"68c68076-cce8-4ea3-a5c8-15aaaa2ce3e6",
"f5fc3d1b-e5f3-4f9f-825a-1b70bb4ca014"
],
"ref": null
}
}
And here's what upscaled_urls
look like: