> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.beatapi.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.beatapi.io/_mcp/server.

# MiniMax H3 Image Highspeed

POST https://api.beatapi.io/v1/images/tasks
Content-Type: application/json

Generate or edit an image from text and up to 16 reference images, at 1K, 2K or 4K or at an exact pixel size, billed by the tokens each render uses.- Asynchronous: the create call returns a task ID in a moment; the image arrives when the task succeeds.
- One image per task. To get several images, create several tasks.
- Text to image, or edit and combine up to 16 reference images given as public HTTPS links.
- Choose the frame with `resolution` and `aspect_ratio`, or with one exact `size` such as `2720x1536`. Never both. `aspect_ratio` defaults to `auto`, which lets the model choose the frame from the prompt and any images.
- Billed by tokens: text input (the prompt, including MiniMax’s prompt enhancement), reference-image input and image output, each at its own per-1M-token rate. The per-image prices below are estimates. The default `resolution` is `4K`; `1K` and `2K` use the same output tokens and so cost the same.
- The result is a `png` (the default), `jpeg` or `webp` file, chosen with `output_format`. A failed task costs nothing.MiniMax H3 Image Highspeed is the Highspeed line of MiniMax’s image model. It takes the same request as `minimax-h3-image`, billed by tokens at higher rates for image input and image output.POST/v1/images/tasksTry itOpens this model in the API Explorer. Enter your BeatAPI API key to create a task: the call is real and is billed to your own balance.## Model IDsBoth MiniMax H3 Image models use this endpoint and take the same fields. The values below come straight from the gateway contract.| Model ID                         | `resolution`     | Max `images` | `output_format`       | About it                                                                                                        |
| -------------------------------- | ---------------- | ------------ | --------------------- | --------------------------------------------------------------------------------------------------------------- |
| `minimax-h3-image`               | `1K`, `2K`, `4K` | 16           | `png`, `jpeg`, `webp` | MiniMax’s image model. See the price table for its per-token rates.                                             |
| **`minimax-h3-image-highspeed`** | `1K`, `2K`, `4K` | 16           | `png`, `jpeg`, `webp` | The Highspeed line. Same fields and limits; higher rates for image input and image output, see the price table. |## Endpoint and authentication`POST https://api.beatapi.io/v1/images/tasks`Authorization
string
RequiredYour BeatAPI API key, sent as `Bearer <BEATAPI_API_KEY>`. Create keys in the [Dashboard](https://beatapi.io/dashboard). Keep keys on your server; never ship them in a browser or mobile app.Send the body as JSON with `Content-Type: application/json`. `Idempotency-Key` is optional: send a unique value (at most 255 characters) per logical request and reuse it only to retry that exact body. Within 24 hours a retry with the same key and body returns the first response again with `Idempotent-Replayed: true`; the same key with a different body returns `409 idempotency_conflict`. Responses other than 2xx are not stored, so a retry after a 400 or 402 runs again.## How a request works`POST` the parameters below to the endpoint. A `201` means the task was accepted and its price reserved from your balance; the work runs in the background. Save `data.id`.Call `GET /v1/tasks/{task_id}` and wait `data.poll_after_seconds` between calls (5 s for images, 8 s for videos) until `status` is `succeeded` or `failed`. Or register a [webhook](/webhooks) for `task.succeeded` and `task.failed`; keep polling as the fallback, because a task stopped by the processing timeout sends no event.On `succeeded`, download every `data.output.media[].url` and store the files you need; BeatAPI does not promise how long result URLs stay available. On `failed`, read `data.error_code` and `data.error_message`: the reserved amount was returned to your balance, and `data.retryable` says whether sending the same request again can succeed.## Input modes| Mode                   | Required inputs             | Notes                                                                                   |
| ---------------------- | --------------------------- | --------------------------------------------------------------------------------------- |
| Text to image          | `model`, `prompt`           | Leave out `images`.                                                                     |
| Edit or combine images | `model`, `prompt`, `images` | 1 to 16 public HTTPS image links. Describe in `prompt` what to change, keep or combine. |## Request parametersmodel
string
RequiredThe model to run.**Value**: `minimax-h3-image-highspeed`**If the value is wrong**- Missing: `"model" is required`
- Unknown model ID: `"model" minimax-image-9 is not catalogued`
- A video model sent to this endpoint: `"model" seedance-2.5 is served by POST /v1/videos/tasks, not this endpoint`prompt
string
RequiredWhat to draw, or what to change in the reference images. Plain language works best: subject, style, lighting, composition, and any text that must appear in the image.**Length**: 1–5000 characters- Length is counted in characters (a CJK character counts as one).
- When you send `images`, say which image does what, for example "Use the first image for the product and the second for the background".
- MiniMax’s prompt enhancement is on for every order. It adds text tokens to the input, which are billed at the text-input rate.**If the value is wrong**- Missing: `"prompt" is required`
- Empty or longer than the limit: `"prompt" has an unsupported length`
- Not a string: `"prompt" must be a string`images
string[]
OptionalReference images to edit or combine. Sending this field switches the request from text-to-image to image editing.**Items**: 1–16  \
Each item is a public `https://` URL. For a local file, [upload it first](/quick-guide#upload-an-input-file) with `POST /v1/files` and pass the returned `data.url`.- Each link must return the image file itself (PNG, JPEG or WebP) over public HTTPS, at most 50 MB. The gateway downloads the first bytes of every link before creating the task and recognises the type from those bytes, not from the file name or `Content-Type`.
- Links to web pages, login walls, expired signed URLs or hotlink-protected hosts are refused, because they do not return an image.
- Positions in error messages are 0-based: `images[0]` is the first link.
- The reference images are billed as image input, at their own per-1M-token rate (see Pricing).**If the value is wrong**- More than the maximum: `"images" accepts at most 16 items`
- An empty array: `"images" requires at least 1 item`
- Not an https\:// link: `"images[0]" must be a public HTTPS URL`
- A private or unsafe address: `"images[0]" must be a publicly reachable HTTPS image URL`
- The host answers with a 4xx error: `"images[0]" could not be downloaded: the URL returned HTTP 404`
- The link returns something other than PNG, JPEG or WebP: `"images[0]" is not a PNG, JPEG or WebP image: the URL returned text/html`
- Larger than 50 MB: `"images[2]" is 63.4 MB; images must be 50 MB or smaller`**Example**```json
"images": [
  "https://cdn.beatapi.io/samples/smart-bottle.png",
  "https://cdn.beatapi.io/samples/neon-singer.png"
]
```aspect_ratio
string
OptionalDefault: autoShape of the image as width:height. Send it together with `resolution`, or leave both out and send `size`.**Allowed values**: `auto`, `1:1`, `3:2`, `2:3`, `4:3`, `3:4`, `5:4`, `4:5`, `16:9`, `9:16`, `2:1`, `1:2`, `3:1`, `1:3`, `21:9`, `9:21`  \
**Default**: `auto`- The default is `auto`: the model chooses the frame from the prompt and from the reference images, if any. Name a ratio when the shape matters.
- Panoramic shapes `2:1`, `1:2`, `3:1`, `1:3`, `21:9` and `9:21` are accepted. The widest or tallest frame is 3:1.
- Not allowed together with `size`.**If the value is wrong**- A value not in the list: `"aspect_ratio" must be one of: [auto 1:1 3:2 2:3 4:3 3:4 5:4 4:5 16:9 9:16 2:1 1:2 3:1 1:3 21:9 9:21]`
- Sent together with `size`: `"size" already fixes the output; do not send "aspect_ratio" with it`resolution
string
OptionalDefault: 4KSize class of the image: `1K`, `2K` or `4K`. A larger class gives a larger image; the exact pixel size depends on `aspect_ratio` and is decided by the model.**Allowed values**: `1K`, `2K`, `4K`  \
**Default**: `4K`- If you leave the field out, `4K` is used.
- `1K` and `2K` use the same output tokens, so they cost the same. `4K` uses about four times as many and costs more (see Pricing).
- Use the capital K: `2k` is refused.
- This page does not promise exact pixel dimensions for a class. If you need an exact frame, send `size`.
- Not allowed together with `size`, which carries its own size.**If the value is wrong**- A value not in the list: `"resolution" must be one of: [1K 2K 4K]`
- Sent together with `size`: `"size" already fixes the output; do not send "resolution" with it`size
string
OptionalAn exact output frame as `WIDTHxHEIGHT` in pixels, for example `2720x1536`. It replaces `resolution` and `aspect_ratio`.- The total must be between 655,360 and 20,000,000 pixels, and the long edge at most three times the short edge. There is no edge multiple to respect.
- The frame is rendered exactly as asked and never rounded.
- The separator can be `x`, `X` or `×`; spaces around it are ignored.
- Billing follows the tokens the render uses: a larger frame uses more output tokens and so costs more (see Pricing).
- Do not send `resolution` or `aspect_ratio` with it, even the default values.**If the value is wrong**- Not a string: `"size" must be a string`
- Not in WIDTHxHEIGHT form (a number alone, `auto`, a comma): `"size" must be WIDTHxHEIGHT in pixels, for example 2720x1536`
- Too few or too many pixels: `"size" must have between 655,360 and 20,000,000 pixels; 512x512 has 262,144`
- Wider or taller than 3:1: `"size" must not be wider or taller than 3:1`
- Sent with `resolution`: `"size" already fixes the output; do not send "resolution" with it`
- Sent with `aspect_ratio`: `"size" already fixes the output; do not send "aspect_ratio" with it`**Example**```json
"size": "2720x1536"
```output_format
string
OptionalDefault: pngThe file type of the image: `png`, `jpeg` or `webp`.**Allowed values**: `png`, `jpeg`, `webp`  \
**Default**: `png`- The default is `png`.
- The format does not change the price.
- Read `mime_type` on the output for the type of the stored file.**If the value is wrong**- A value not in the list: `"output_format" must be one of: [png jpeg webp]`**Example**```json
"output_format": "webp"
```The gateway also checks these combinations before creating the task:- size is WIDTHxHEIGHT and replaces resolution and aspect\_ratio: 655,360-20,000,000 pixels in total, at most 3:1; it is rendered exactly, never rounded
- billed per token at the listed rates for the tokens each render uses (text input including prompt enhancement, reference images, image output); the listed per-image prices are estimates; 1K and 2K use the same output tokens
- aspect\_ratio auto lets the model choose the frame from the prompt and any images## Input media limitsThe gateway reads every input before the task is created and refuses one outside these limits with a `400 bad_request` that names the input. Nothing is charged.- Reference images: PNG, JPEG or WebP, recognised from the file content; at most 50 MB each (decimal megabytes; checked when the host states the size); 1 to 16 links. GIF, HEIC and SVG are refused.
- No pixel or aspect-ratio limit is checked on the reference images themselves.
- If a host does not answer in time, the link is not refused at create. The gateway fetches it again when the task is dispatched, and a link that still cannot be fetched fails the task, which is refunded.
- Have a local file? Upload it with `POST /v1/files` and pass the returned `data.url`.## Choose the frame: `resolution` and `aspect_ratio`, or `size`There are two ways to say how big and how wide the image is, and they exclude each other:- **Tier and ratio.** Send `resolution` (`1K`, `2K` or `4K`) and, if you want a shape, `aspect_ratio`. Leave both out and you get `4K` and `auto`: the model chooses the frame.
- **Exact size.** Send `size` alone, for example `2720x1536`: 655,360 to 20,000,000 pixels, at most 3:1, rendered exactly.Sending `size` with `resolution` or with `aspect_ratio` is refused with `"size" already fixes the output; do not send "resolution" with it` (or `"aspect_ratio"`). The check applies even when the other field holds its default value.## What the estimate assumesThe per-image prices in the table below are estimates. Each one assumes 3,000 text tokens (the prompt and MiniMax’s prompt enhancement) and the output tokens of the tier, and no reference images. What you are charged is settled to the tokens the render actually used.| `resolution` | Output tokens in the estimate |
| ------------ | ----------------------------- |
| `1K`         | 4,096                         |
| `2K`         | 4,096                         |
| `4K`         | 16,384                        |## Fields this model does not acceptThe image endpoint knows a few fields that other image models use. Sending one of them here is refused instead of being ignored, so you never pay for a setting that had no effect:- `background`, `quality`, `seed`, `enhance_prompt` → `field "background" is not supported by model minimax-h3-image-highspeed` (with the field you sent and the model you called).
- Any other unknown field, such as `n` or `moderation` → `unknown field: n`. There is no `n`: one task makes one image.## Request examples```bash title="cURL"
curl --request POST \
  --url https://api.beatapi.io/v1/images/tasks \
  --header "Authorization: Bearer $BEATAPI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "minimax-h3-image-highspeed",
  "prompt": "A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field",
  "aspect_ratio": "3:2",
  "resolution": "2K"
}'
``````python title="Python"
import os
import requests

response = requests.post(
    "https://api.beatapi.io/v1/images/tasks",
    headers={"Authorization": f"Bearer {os.environ['BEATAPI_API_KEY']}"},
    json={
      "model": "minimax-h3-image-highspeed",
      "prompt": "A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field",
      "aspect_ratio": "3:2",
      "resolution": "2K"
    },
    timeout=60,
)
body = response.json()
if not response.ok:
    raise RuntimeError(f"{response.status_code} {body['error']['code']}: {body['error']['message']}")
task = body["data"]
print(task["id"], task["status"])
``````javascript title="JavaScript"
const response = await fetch('https://api.beatapi.io/v1/images/tasks', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.BEATAPI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "model": "minimax-h3-image-highspeed",
    "prompt": "A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field",
    "aspect_ratio": "3:2",
    "resolution": "2K"
  }),
});
const body = await response.json();
if (!response.ok) throw new Error(`${response.status} ${body.error.code}: ${body.error.message}`);
console.log(body.data.id, body.data.status);
```### Text to imageA 2K landscape image from a prompt, with a tier and a ratio.```bash
curl --request POST \
  --url https://api.beatapi.io/v1/images/tasks \
  --header "Authorization: Bearer $BEATAPI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "minimax-h3-image-highspeed",
  "prompt": "A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field",
  "aspect_ratio": "3:2",
  "resolution": "2K"
}'
```### Let the model choose the frameOnly a prompt: `resolution` is `4K` and `aspect_ratio` is `auto`, so the model chooses the frame.```bash
curl --request POST \
  --url https://api.beatapi.io/v1/images/tasks \
  --header "Authorization: Bearer $BEATAPI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "minimax-h3-image-highspeed",
  "prompt": "A tall, narrow travel poster of a mountain railway at dawn, bold flat colours"
}'
```### Edit one imageChange the background and keep the product.```bash
curl --request POST \
  --url https://api.beatapi.io/v1/images/tasks \
  --header "Authorization: Bearer $BEATAPI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "minimax-h3-image-highspeed",
  "prompt": "Keep the bottle exactly as it is. Replace the background with a sunlit kitchen counter and add a soft reflection under the bottle.",
  "images": [
    "https://cdn.beatapi.io/samples/smart-bottle.png"
  ],
  "aspect_ratio": "1:1",
  "resolution": "2K"
}'
```### Combine several imagesName each reference in the prompt by its position.```bash
curl --request POST \
  --url https://api.beatapi.io/v1/images/tasks \
  --header "Authorization: Bearer $BEATAPI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "minimax-h3-image-highspeed",
  "prompt": "Place the bottle from the first image on a neon-lit stage like the one in the second image. Keep the bottle label readable.",
  "images": [
    "https://cdn.beatapi.io/samples/smart-bottle.png",
    "https://cdn.beatapi.io/samples/neon-singer.png"
  ],
  "aspect_ratio": "16:9",
  "resolution": "2K"
}'
```### Exact sizeA 2720x1536 frame as WebP. `size` stands alone: no `resolution`, no `aspect_ratio`.```bash
curl --request POST \
  --url https://api.beatapi.io/v1/images/tasks \
  --header "Authorization: Bearer $BEATAPI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "minimax-h3-image-highspeed",
  "prompt": "A flat illustration of a lighthouse on a cliff at dawn, pastel colours, clean shapes",
  "size": "2720x1536",
  "output_format": "webp"
}'
```## Responses### Create a task (201)The task object. `output` is `null` until the task succeeds. Fields marked “while running” disappear once the task finishes.```json
{
  "data": {
    "id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
    "object": "task",
    "task_kind": "image",
    "capability_id": "minimax-h3-image-highspeed",
    "capability_version": 1,
    "media_type": "image",
    "model": "minimax-h3-image-highspeed",
    "status": "queued",
    "stage": "queued",
    "created_at": 1791993600,
    "updated_at": 1791993600,
    "completed_at": null,
    "poll_after_seconds": 5,
    "output": null,
    "usage": {
      "credits_reserved": 0.026621,
      "credits_settled": 0,
      "credits_refunded": 0,
      "credits_charged": 0.026621
    },
    "request_id": "req_5f0c2a9e4b7d4e31",
    "error_code": null,
    "error_message": null
  }
}
```| Field                                  | Type              | Description                                                                                                                              |
| -------------------------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `data.id`                              | `string`          | Task ID: `task_` followed by 32 letters and digits. Use it to poll and to match webhook events.                                          |
| `data.object`                          | `string`          | Always `task`.                                                                                                                           |
| `data.task_kind`                       | `string`          | `image` or `video`.                                                                                                                      |
| `data.capability_id`                   | `string`          | The model ID you sent.                                                                                                                   |
| `data.capability_version`              | `integer`         | Contract version of the model, currently `1`.                                                                                            |
| `data.media_type`                      | `string`          | `image` or `video`.                                                                                                                      |
| `data.model`                           | `string`          | The model ID you sent (same as `capability_id`).                                                                                         |
| `data.status`                          | `string`          | `queued`, `processing`, `succeeded` or `failed`. Only the last two are final.                                                            |
| `data.stage`                           | `string`          | Repeats `status`; kept for older clients.                                                                                                |
| `data.created_at`                      | `integer`         | When the task was created, Unix seconds.                                                                                                 |
| `data.updated_at`                      | `integer`         | Last change, Unix seconds.                                                                                                               |
| `data.completed_at`                    | `integer \| null` | When the task finished, Unix seconds; `null` while it runs.                                                                              |
| `data.poll_after_seconds`              | `integer`         | While running: how long to wait before the next poll (5 for images, 8 for videos).                                                       |
| `data.typical_seconds`                 | `object`          | While running, when enough recent tasks exist: `p50` and `p90` completion times in seconds over the last `window`, from `samples` tasks. |
| `data.output`                          | `object \| null`  | The result; `null` until `status` is `succeeded`. See the output fields below.                                                           |
| `data.usage.credits_reserved`          | `number`          | USD held from your balance when the task was created.                                                                                    |
| `data.usage.credits_charged`           | `number`          | USD this task costs; `0` on a failed task.                                                                                               |
| `data.usage.credits_settled`           | `number`          | USD finally taken; set when the task succeeds, otherwise `0`.                                                                            |
| `data.usage.credits_refunded`          | `number`          | USD returned to your balance; equals the reservation on a failed task once the refund is recorded.                                       |
| `data.usage.billable_duration_seconds` | `integer`         | Video only: the seconds the price is based on. Absent when the model reports no duration.                                                |
| `data.request_id`                      | `string`          | Request ID. Include it when you contact support.                                                                                         |
| `data.error_code`                      | `string \| null`  | Failure code; `null` unless the task failed.                                                                                             |
| `data.error_message`                   | `string \| null`  | What went wrong and what to change; `null` unless the task failed.                                                                       |### Finished task`GET /v1/tasks/{task_id}` returns HTTP 200 with `status: "succeeded"` and the result in `data.output`.```json
{
  "data": {
    "id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
    "object": "task",
    "task_kind": "image",
    "capability_id": "minimax-h3-image-highspeed",
    "capability_version": 1,
    "media_type": "image",
    "model": "minimax-h3-image-highspeed",
    "status": "succeeded",
    "stage": "succeeded",
    "created_at": 1791993600,
    "updated_at": 1791993690,
    "completed_at": 1791993690,
    "output": {
      "media": [
        {
          "type": "image",
          "url": "https://media.beatapi.io/outputs/task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ/0.png",
          "mime_type": "image/png"
        }
      ],
      "r2_url": "https://media.beatapi.io/outputs/task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ/0.png"
    },
    "usage": {
      "credits_reserved": 0.026621,
      "credits_settled": 0.026621,
      "credits_refunded": 0,
      "credits_charged": 0.026621
    },
    "request_id": "req_5f0c2a9e4b7d4e31",
    "error_code": null,
    "error_message": null
  }
}
```#### Output fields| Field                      | Type       | Description                                                                                        |
| -------------------------- | ---------- | -------------------------------------------------------------------------------------------------- |
| `output.media`             | `object[]` | The generated files; one item for this model.                                                      |
| `output.media[].type`      | `string`   | Always `image`.                                                                                    |
| `output.media[].url`       | `string`   | HTTPS link to the stored image. Download and keep it; no retention period is promised.             |
| `output.media[].mime_type` | `string`   | The type of the stored file: `image/png`, `image/jpeg` or `image/webp`, following `output_format`. |
| `output.r2_url`            | `string`   | The first media URL again, for older clients. Read `media` instead.                                |### Failed taskA failed task is still HTTP 200 on `GET /v1/tasks/{task_id}`: the failure is in the body. The reservation is returned in full, so nothing is charged.```json
{
  "data": {
    "id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
    "object": "task",
    "task_kind": "image",
    "capability_id": "minimax-h3-image-highspeed",
    "capability_version": 1,
    "media_type": "image",
    "model": "minimax-h3-image-highspeed",
    "status": "failed",
    "stage": "failed",
    "created_at": 1791993600,
    "updated_at": 1791993690,
    "completed_at": 1791993690,
    "output": null,
    "usage": {
      "credits_reserved": 0.026621,
      "credits_settled": 0,
      "credits_refunded": 0.026621,
      "credits_charged": 0
    },
    "retryable": true,
    "request_id": "req_5f0c2a9e4b7d4e31",
    "error_code": "processing_failed",
    "error_message": "The task failed during processing on our side. Retry; a failed task is refunded."
  }
}
```| Field                | Type      | Description                                                                                                                                                                                                            |
| -------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data.error_code`    | `string`  | One of `bad_request` and `content_policy_violation` (change the request) or `processing_unavailable`, `processing_timeout`, `processing_failed` and `result_transfer_failed` (try again later). See [Errors](/errors). |
| `data.error_message` | `string`  | A sentence that names the problem and the fix.                                                                                                                                                                         |
| `data.retryable`     | `boolean` | Present only on a failed task: `true` when the same request can succeed if you send it again.                                                                                                                          |
| `data.usage`         | `object`  | Once the refund is recorded (normally at the moment the task fails): `credits_charged` and `credits_settled` are `0`, and `credits_refunded` equals `credits_reserved`.                                                |## Complete exampleCreate a task, wait for it with the server’s polling hint, and print the result URLs. Set `BEATAPI_API_KEY` in your environment and install `requests`.```python
import os
import time
import uuid

import requests

API = "https://api.beatapi.io"
HEADERS = {"Authorization": f"Bearer {os.environ['BEATAPI_API_KEY']}"}


def create_task(body: dict) -> dict:
    # One Idempotency-Key per logical request: a retry with the same key cannot create a second task.
    headers = {**HEADERS, "Idempotency-Key": str(uuid.uuid4())}
    for attempt in range(3):
        response = requests.post(f"{API}/v1/images/tasks", headers=headers, json=body, timeout=60)
        if response.status_code in (429, 503) and attempt < 2:
            time.sleep(int(response.headers.get("Retry-After", 10)))
            continue
        break
    try:
        payload = response.json()
    except ValueError:  # an edge error page is not JSON
        response.raise_for_status()
        raise
    if not response.ok:
        error = payload["error"]
        raise RuntimeError(f"{response.status_code} {error['code']}: {error['message']} (request_id={error.get('request_id')})")
    return payload["data"]


def wait_for_task(task_id: str, timeout_seconds: int = 1800) -> dict:
    deadline = time.monotonic() + timeout_seconds
    while time.monotonic() < deadline:
        response = requests.get(f"{API}/v1/tasks/{task_id}", headers=HEADERS, timeout=30)
        if response.status_code == 429 or response.status_code >= 500:
            time.sleep(int(response.headers.get("Retry-After", 10)))
            continue
        response.raise_for_status()
        task = response.json()["data"]
        if task["status"] in ("succeeded", "failed"):
            return task
        time.sleep(task.get("poll_after_seconds", 5))
    raise TimeoutError(f"task {task_id} is still running; keep polling later")


task = create_task({
  "model": "minimax-h3-image-highspeed",
  "prompt": "A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field",
  "aspect_ratio": "3:2",
  "resolution": "2K"
})
print("created", task["id"])
task = wait_for_task(task["id"])
if task["status"] == "failed":
    raise SystemExit(f"{task['error_code']}: {task['error_message']}")
for item in task["output"]["media"]:
    print(item["url"])
```## Billing- Billed by tokens at the per-1M-token rates in the table below: text input (the prompt, including MiniMax’s prompt enhancement), image input (the reference images in `images`) and image output. The model counts the tokens; the `resolution` or `size`, the prompt and the reference images all change the count.
- The per-image prices are estimates for one render of each `resolution` without reference images, at 3,000 text tokens and the output tokens in the table above. `1K` and `2K` use the same output tokens and so have the same estimate.
- When the task is created, the estimate for its tier is reserved from your balance, and from the key’s quota if it has one. When it succeeds, the charge is settled to the tokens the render actually used, so the final `data.usage` can differ from the reservation. A request refused before a task exists costs nothing.
- A failed task is refunded in full.Current list prices, the same as on [Pricing](https://beatapi.io/pricing). An account with a negotiated discount pays less; `data.usage` on the task always shows the amount actually charged.| Option                                         | List price (USD) |
| ---------------------------------------------- | ---------------- |
| 1 image · 1K · estimate at the measured tokens | \$0.026621       |
| 1 image · 2K · estimate at the measured tokens | \$0.026621       |
| 1 image · 4K · estimate at the measured tokens | \$0.091993       |
| Text input · per 1M tokens                     | \$1.61           |
| Image input · per 1M tokens                    | \$2.1            |
| Image output · per 1M tokens                   | \$5.32           |## Common errors| Error or symptom                                                                  | Cause                                                                                    | Fix                                                                                 |
| --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| 400 `"size" already fixes the output; do not send "resolution" with it`           | `size` was sent together with `resolution` or `aspect_ratio`, even at its default value. | Send `size` alone, or `resolution` and `aspect_ratio` without `size`.               |
| 400 `"size" must have between 655,360 and 20,000,000 pixels; 512x512 has 262,144` | The frame has too few or too many pixels.                                                | Keep the total between 655,360 and 20,000,000 pixels.                               |
| 400 `"size" must not be wider or taller than 3:1`                                 | The long edge is more than three times the short edge.                                   | Use a frame of at most 3:1, for example `3000x1000`.                                |
| 400 `"resolution" must be one of: [1K 2K 4K]`                                     | Lower-case `2k`, `8K`, or a pixel size such as `2048x2048` in `resolution`.              | Send `1K`, `2K` or `4K`, or use the `size` field for pixels.                        |
| 400 `"output_format" must be one of: [png jpeg webp]`                             | `gif`, `jpg` or another file type.                                                       | Send `png`, `jpeg` or `webp`, or leave the field out for `png`.                     |
| 400 `field "background" is not supported by model minimax-h3-image-highspeed`     | A field from another image model (`background`, `quality`, `seed`, `enhance_prompt`).    | Remove the field.                                                                   |
| 400 `unknown field: n`                                                            | Asking for several images in one task.                                                   | Remove `n` and create one task per image.                                           |
| 400 `"images[0]" must be a public HTTPS URL`                                      | An `http://` link, a `data:` URI or a local path.                                        | Host the file on HTTPS, or upload it with `POST /v1/files` and use `data.url`.      |
| 400 `"images[1]" is not a PNG, JPEG or WebP image: the URL returned text/html`    | The link opens a web page, a login page or an expired signed URL instead of the file.    | Link directly to the image file.                                                    |
| 400 `"images[0]" could not be downloaded: the URL returned HTTP 403`              | The host blocks downloads from servers (hotlink protection or private bucket).           | Make the file public, or upload it with `POST /v1/files`.                           |
| The charge differs from the per-image price                                       | The charge is settled to the tokens the render used; the per-image price is an estimate. | Read `data.usage` on the finished task.                                             |
| Task `failed` with `content_policy_violation`                                     | The prompt, a reference image or the generated image was refused by moderation.          | Change the prompt or the image. Retrying unchanged fails again; nothing is charged. |
| Task `failed` with `processing_timeout`                                           | The image did not finish within the processing window.                                   | Retry; the failed task was refunded.                                                |## HTTP errors at a glanceErrors before a task exists arrive as a non-2xx response, and nothing is charged. Branch on `error.code` or `error.retryable`; `message` names the problem. The full list and retry policy are on [Errors](/errors).```json
{
  "error": {
    "code": "bad_request",
    "message": "\"prompt\" is required",
    "retryable": false,
    "request_id": "req_5f0c2a9e4b7d4e31"
  }
}
```| HTTP status | `error.code`                                                                                  | What to do                                                                                                            |
| ----------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| 400         | `bad_request`, `content_policy_violation`                                                     | Fix the request; the message names the field. Do not retry unchanged.                                                 |
| 401         | `missing_api_key`, `invalid_api_key` (older clients may see `unauthorized`)                   | Send a valid key as `Authorization: Bearer <key>`.                                                                    |
| 402         | `insufficient_credits`                                                                        | Top up, or raise the key’s quota, then send it again.                                                                 |
| 403         | `forbidden`                                                                                   | The key or account may not use this model (for example, free credit only covers some models). Do not retry unchanged. |
| 404         | `not_found`                                                                                   | On `GET /v1/tasks/{task_id}`: the task does not exist for this key’s account. Check the ID.                           |
| 409         | `idempotency_conflict`                                                                        | Use a new `Idempotency-Key`, or wait for the first request with this key to finish.                                   |
| 429         | `rate_limit_exceeded`                                                                         | Wait `Retry-After` seconds (also `error.retry_after_seconds`), then retry.                                            |
| 500         | `internal_error`                                                                              | Retry with backoff; contact support with `request_id` if it continues.                                                |
| 503         | `processing_unavailable`, `processing_timeout`, `processing_failed`, `result_transfer_failed` | Nothing was charged. Retry with exponential backoff.                                                                  |

Reference: https://docs.beatapi.io/api-reference/image-api/minimax-h3-image-highspeed

## Authentication

- `Authorization` header (bearer token, required) — Send your API key as `Authorization: Bearer <BEATAPI_API_KEY>`.

## Servers

- `https://api.beatapi.io` (Direct, default)
- `https://api.beatapi.io` (API)

## Request

### Headers

- `Idempotency-Key` (string, optional) — Send the body as JSON with `Content-Type: application/json`. `Idempotency-Key` is optional: send a unique value (at most 255 characters) per logical request and reuse it only to retry that exact body. Within 24 hours a retry with the same key and body returns the first response again with `Idempotent-Replayed: true`; the same key with a different body returns `409 idempotency_conflict`. Responses other than 2xx are not stored, so a retry after a 400 or 402 runs again.

### Body (application/json)

This endpoint expects a MinimaxH3ImageHighspeedRequest.

- `model` (enum, required) — The model to run. **Value**: `minimax-h3-image-highspeed` **If the value is wrong** - Missing: `"model" is required` - Unknown model ID: `"model" minimax-image-9 is not catalogued` - A video model sent to this endpoint: `"model" seedance-2.5 is served by POST /v1/videos/tasks, not this endpoint`
  - Allowed values: `minimax-h3-image-highspeed`
- `prompt` (string, required) — What to draw, or what to change in the reference images. Plain language works best: subject, style, lighting, composition, and any text that must appear in the image. **Length**: 1–5000 characters - Length is counted in characters (a CJK character counts as one). - When you send `images`, say which image does what, for example "Use the first image for the product and the second for the background". - MiniMax’s prompt enhancement is on for every order. It adds text tokens to the input, which are billed at the text-input rate. **If the value is wrong** - Missing: `"prompt" is required` - Empty or longer than the limit: `"prompt" has an unsupported length` - Not a string: `"prompt" must be a string`
- `aspect_ratio` (enum, optional, default: auto) — Shape of the image as width:height. Send it together with `resolution`, or leave both out and send `size`. **Allowed values**: `auto`, `1:1`, `3:2`, `2:3`, `4:3`, `3:4`, `5:4`, `4:5`, `16:9`, `9:16`, `2:1`, `1:2`, `3:1`, `1:3`, `21:9`, `9:21` **Default**: `auto` - The default is `auto`: the model chooses the frame from the prompt and from the reference images, if any. Name a ratio when the shape matters. - Panoramic shapes `2:1`, `1:2`, `3:1`, `1:3`, `21:9` and `9:21` are accepted. The widest or tallest frame is 3:1. - Not allowed together with `size`. **If the value is wrong** - A value not in the list: `"aspect_ratio" must be one of: [auto 1:1 3:2 2:3 4:3 3:4 5:4 4:5 16:9 9:16 2:1 1:2 3:1 1:3 21:9 9:21]` - Sent together with `size`: `"size" already fixes the output; do not send "aspect_ratio" with it`
  - Allowed values: `auto`, `1:1`, `3:2`, `2:3`, `4:3`, `3:4`, `5:4`, `4:5`, `16:9`, `9:16`, `2:1`, `1:2`, `3:1`, `1:3`, `21:9`, `9:21`
- `images` (list of string, optional) — Reference images to edit or combine. Sending this field switches the request from text-to-image to image editing. **Items**: 1–16 Each item is a public `https://` URL. For a local file, [upload it first](/quick-guide#upload-an-input-file) with `POST /v1/files` and pass the returned `data.url`. - Each link must return the image file itself (PNG, JPEG or WebP) over public HTTPS, at most 50 MB. The gateway downloads the first bytes of every link before creating the task and recognises the type from those bytes, not from the file name or `Content-Type`. - Links to web pages, login walls, expired signed URLs or hotlink-protected hosts are refused, because they do not return an image. - Positions in error messages are 0-based: `images[0]` is the first link. - The reference images are billed as image input, at their own per-1M-token rate (see Pricing). **If the value is wrong** - More than the maximum: `"images" accepts at most 16 items` - An empty array: `"images" requires at least 1 item` - Not an https:// link: `"images[0]" must be a public HTTPS URL` - A private or unsafe address: `"images[0]" must be a publicly reachable HTTPS image URL` - The host answers with a 4xx error: `"images[0]" could not be downloaded: the URL returned HTTP 404` - The link returns something other than PNG, JPEG or WebP: `"images[0]" is not a PNG, JPEG or WebP image: the URL returned text/html` - Larger than 50 MB: `"images[2]" is 63.4 MB; images must be 50 MB or smaller` **Example** ```json "images": [ "https://cdn.beatapi.io/samples/smart-bottle.png", "https://cdn.beatapi.io/samples/neon-singer.png" ] ```
- `output_format` (enum, optional, default: png) — The file type of the image: `png`, `jpeg` or `webp`. **Allowed values**: `png`, `jpeg`, `webp` **Default**: `png` - The default is `png`. - The format does not change the price. - Read `mime_type` on the output for the type of the stored file. **If the value is wrong** - A value not in the list: `"output_format" must be one of: [png jpeg webp]` **Example** ```json "output_format": "webp" ```
  - Allowed values: `png`, `jpeg`, `webp`
- `resolution` (enum, optional, default: 4K) — Size class of the image: `1K`, `2K` or `4K`. A larger class gives a larger image; the exact pixel size depends on `aspect_ratio` and is decided by the model. **Allowed values**: `1K`, `2K`, `4K` **Default**: `4K` - If you leave the field out, `4K` is used. - `1K` and `2K` use the same output tokens, so they cost the same. `4K` uses about four times as many and costs more (see Pricing). - Use the capital K: `2k` is refused. - This page does not promise exact pixel dimensions for a class. If you need an exact frame, send `size`. - Not allowed together with `size`, which carries its own size. **If the value is wrong** - A value not in the list: `"resolution" must be one of: [1K 2K 4K]` - Sent together with `size`: `"size" already fixes the output; do not send "resolution" with it`
  - Allowed values: `1K`, `2K`, `4K`
- `size` (string, optional) — An exact output frame as `WIDTHxHEIGHT` in pixels, for example `2720x1536`. It replaces `resolution` and `aspect_ratio`. - The total must be between 655,360 and 20,000,000 pixels, and the long edge at most three times the short edge. There is no edge multiple to respect. - The frame is rendered exactly as asked and never rounded. - The separator can be `x`, `X` or `×`; spaces around it are ignored. - Billing follows the tokens the render uses: a larger frame uses more output tokens and so costs more (see Pricing). - Do not send `resolution` or `aspect_ratio` with it, even the default values. **If the value is wrong** - Not a string: `"size" must be a string` - Not in WIDTHxHEIGHT form (a number alone, `auto`, a comma): `"size" must be WIDTHxHEIGHT in pixels, for example 2720x1536` - Too few or too many pixels: `"size" must have between 655,360 and 20,000,000 pixels; 512x512 has 262,144` - Wider or taller than 3:1: `"size" must not be wider or taller than 3:1` - Sent with `resolution`: `"size" already fixes the output; do not send "resolution" with it` - Sent with `aspect_ratio`: `"size" already fixes the output; do not send "aspect_ratio" with it` **Example** ```json "size": "2720x1536" ```

## Response

### 201

The task object. `output` is `null` until the task succeeds. Fields marked “while running” disappear once the task finishes.

- `map from string to any`

## Errors

### 400 Bad Request Error

`bad_request`, `content_policy_violation` Fix the request; the message names the field. Do not retry unchanged.

- `map from string to any`

### 401 Unauthorized Error

`missing_api_key`, `invalid_api_key` (older clients may see `unauthorized`) Send a valid key as `Authorization: Bearer <key>`.

- `map from string to any`

### 402 Payment Required Error

`insufficient_credits` Top up, or raise the key’s quota, then send it again.

- `map from string to any`

### 403 Forbidden Error

`forbidden` The key or account may not use this model (for example, free credit only covers some models). Do not retry unchanged.

- `map from string to any`

### 409 Conflict Error

`idempotency_conflict` Use a new `Idempotency-Key`, or wait for the first request with this key to finish.

- `map from string to any`

### 429 Too Many Requests Error

`rate_limit_exceeded` Wait `Retry-After` seconds (also `error.retry_after_seconds`), then retry.

- `map from string to any`

### 500 Internal Server Error

`internal_error` Retry with backoff; contact support with `request_id` if it continues.

- `map from string to any`

### 503 Service Unavailable Error

`processing_unavailable`, `processing_timeout`, `processing_failed`, `result_transfer_failed` Nothing was charged. Retry with exponential backoff.

- `map from string to any`

## Examples

### Text to image

**Request**

```json
{
  "model": "minimax-h3-image-highspeed",
  "prompt": "A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field",
  "aspect_ratio": "3:2",
  "resolution": "2K"
}
```

**Response**

```json
{
  "data": {
    "capability_id": "minimax-h3-image-highspeed",
    "capability_version": 1,
    "completed_at": null,
    "created_at": 1791993600,
    "error_code": null,
    "error_message": null,
    "id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
    "media_type": "image",
    "model": "minimax-h3-image-highspeed",
    "object": "task",
    "output": null,
    "poll_after_seconds": 5,
    "request_id": "req_5f0c2a9e4b7d4e31",
    "stage": "queued",
    "status": "queued",
    "task_kind": "image",
    "updated_at": 1791993600,
    "usage": {
      "credits_charged": 0.026621,
      "credits_refunded": 0,
      "credits_reserved": 0.026621,
      "credits_settled": 0
    }
  }
}
```

**SDK Code**

```python Text to image
import requests

url = "https://api.beatapi.io/v1/images/tasks"

payload = {
    "model": "minimax-h3-image-highspeed",
    "prompt": "A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field",
    "aspect_ratio": "3:2",
    "resolution": "2K"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Text to image
const url = 'https://api.beatapi.io/v1/images/tasks';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"model":"minimax-h3-image-highspeed","prompt":"A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field","aspect_ratio":"3:2","resolution":"2K"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Text to image
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.beatapi.io/v1/images/tasks"

	payload := strings.NewReader("{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field\",\n  \"aspect_ratio\": \"3:2\",\n  \"resolution\": \"2K\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Text to image
require 'uri'
require 'net/http'

url = URI("https://api.beatapi.io/v1/images/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field\",\n  \"aspect_ratio\": \"3:2\",\n  \"resolution\": \"2K\"\n}"

response = http.request(request)
puts response.read_body
```

```java Text to image
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.beatapi.io/v1/images/tasks")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field\",\n  \"aspect_ratio\": \"3:2\",\n  \"resolution\": \"2K\"\n}")
  .asString();
```

```php Text to image
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.beatapi.io/v1/images/tasks', [
  'body' => '{
  "model": "minimax-h3-image-highspeed",
  "prompt": "A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field",
  "aspect_ratio": "3:2",
  "resolution": "2K"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Text to image
using RestSharp;

var client = new RestClient("https://api.beatapi.io/v1/images/tasks");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field\",\n  \"aspect_ratio\": \"3:2\",\n  \"resolution\": \"2K\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Text to image
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "model": "minimax-h3-image-highspeed",
  "prompt": "A minimalist product photo of a glass water bottle on wet black stone, soft rim light, shallow depth of field",
  "aspect_ratio": "3:2",
  "resolution": "2K"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.beatapi.io/v1/images/tasks")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Let the model choose the frame

**Request**

```json
{
  "model": "minimax-h3-image-highspeed",
  "prompt": "A tall, narrow travel poster of a mountain railway at dawn, bold flat colours"
}
```

**Response**

```json
{
  "data": {
    "capability_id": "minimax-h3-image-highspeed",
    "capability_version": 1,
    "completed_at": null,
    "created_at": 1791993600,
    "error_code": null,
    "error_message": null,
    "id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
    "media_type": "image",
    "model": "minimax-h3-image-highspeed",
    "object": "task",
    "output": null,
    "poll_after_seconds": 5,
    "request_id": "req_5f0c2a9e4b7d4e31",
    "stage": "queued",
    "status": "queued",
    "task_kind": "image",
    "updated_at": 1791993600
  }
}
```

**SDK Code**

```python Let the model choose the frame
import requests

url = "https://api.beatapi.io/v1/images/tasks"

payload = {
    "model": "minimax-h3-image-highspeed",
    "prompt": "A tall, narrow travel poster of a mountain railway at dawn, bold flat colours"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Let the model choose the frame
const url = 'https://api.beatapi.io/v1/images/tasks';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"model":"minimax-h3-image-highspeed","prompt":"A tall, narrow travel poster of a mountain railway at dawn, bold flat colours"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Let the model choose the frame
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.beatapi.io/v1/images/tasks"

	payload := strings.NewReader("{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A tall, narrow travel poster of a mountain railway at dawn, bold flat colours\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Let the model choose the frame
require 'uri'
require 'net/http'

url = URI("https://api.beatapi.io/v1/images/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A tall, narrow travel poster of a mountain railway at dawn, bold flat colours\"\n}"

response = http.request(request)
puts response.read_body
```

```java Let the model choose the frame
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.beatapi.io/v1/images/tasks")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A tall, narrow travel poster of a mountain railway at dawn, bold flat colours\"\n}")
  .asString();
```

```php Let the model choose the frame
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.beatapi.io/v1/images/tasks', [
  'body' => '{
  "model": "minimax-h3-image-highspeed",
  "prompt": "A tall, narrow travel poster of a mountain railway at dawn, bold flat colours"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Let the model choose the frame
using RestSharp;

var client = new RestClient("https://api.beatapi.io/v1/images/tasks");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A tall, narrow travel poster of a mountain railway at dawn, bold flat colours\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Let the model choose the frame
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "model": "minimax-h3-image-highspeed",
  "prompt": "A tall, narrow travel poster of a mountain railway at dawn, bold flat colours"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.beatapi.io/v1/images/tasks")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Edit one image

**Request**

```json
{
  "model": "minimax-h3-image-highspeed",
  "prompt": "Keep the bottle exactly as it is. Replace the background with a sunlit kitchen counter and add a soft reflection under the bottle.",
  "aspect_ratio": "1:1",
  "images": [
    "https://cdn.beatapi.io/samples/smart-bottle.png"
  ],
  "resolution": "2K"
}
```

**Response**

```json
{
  "data": {
    "capability_id": "minimax-h3-image-highspeed",
    "capability_version": 1,
    "completed_at": null,
    "created_at": 1791993600,
    "error_code": null,
    "error_message": null,
    "id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
    "media_type": "image",
    "model": "minimax-h3-image-highspeed",
    "object": "task",
    "output": null,
    "poll_after_seconds": 5,
    "request_id": "req_5f0c2a9e4b7d4e31",
    "stage": "queued",
    "status": "queued",
    "task_kind": "image",
    "updated_at": 1791993600
  }
}
```

**SDK Code**

```python Edit one image
import requests

url = "https://api.beatapi.io/v1/images/tasks"

payload = {
    "model": "minimax-h3-image-highspeed",
    "prompt": "Keep the bottle exactly as it is. Replace the background with a sunlit kitchen counter and add a soft reflection under the bottle.",
    "aspect_ratio": "1:1",
    "images": ["https://cdn.beatapi.io/samples/smart-bottle.png"],
    "resolution": "2K"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Edit one image
const url = 'https://api.beatapi.io/v1/images/tasks';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"model":"minimax-h3-image-highspeed","prompt":"Keep the bottle exactly as it is. Replace the background with a sunlit kitchen counter and add a soft reflection under the bottle.","aspect_ratio":"1:1","images":["https://cdn.beatapi.io/samples/smart-bottle.png"],"resolution":"2K"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Edit one image
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.beatapi.io/v1/images/tasks"

	payload := strings.NewReader("{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"Keep the bottle exactly as it is. Replace the background with a sunlit kitchen counter and add a soft reflection under the bottle.\",\n  \"aspect_ratio\": \"1:1\",\n  \"images\": [\n    \"https://cdn.beatapi.io/samples/smart-bottle.png\"\n  ],\n  \"resolution\": \"2K\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Edit one image
require 'uri'
require 'net/http'

url = URI("https://api.beatapi.io/v1/images/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"Keep the bottle exactly as it is. Replace the background with a sunlit kitchen counter and add a soft reflection under the bottle.\",\n  \"aspect_ratio\": \"1:1\",\n  \"images\": [\n    \"https://cdn.beatapi.io/samples/smart-bottle.png\"\n  ],\n  \"resolution\": \"2K\"\n}"

response = http.request(request)
puts response.read_body
```

```java Edit one image
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.beatapi.io/v1/images/tasks")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"Keep the bottle exactly as it is. Replace the background with a sunlit kitchen counter and add a soft reflection under the bottle.\",\n  \"aspect_ratio\": \"1:1\",\n  \"images\": [\n    \"https://cdn.beatapi.io/samples/smart-bottle.png\"\n  ],\n  \"resolution\": \"2K\"\n}")
  .asString();
```

```php Edit one image
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.beatapi.io/v1/images/tasks', [
  'body' => '{
  "model": "minimax-h3-image-highspeed",
  "prompt": "Keep the bottle exactly as it is. Replace the background with a sunlit kitchen counter and add a soft reflection under the bottle.",
  "aspect_ratio": "1:1",
  "images": [
    "https://cdn.beatapi.io/samples/smart-bottle.png"
  ],
  "resolution": "2K"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Edit one image
using RestSharp;

var client = new RestClient("https://api.beatapi.io/v1/images/tasks");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"Keep the bottle exactly as it is. Replace the background with a sunlit kitchen counter and add a soft reflection under the bottle.\",\n  \"aspect_ratio\": \"1:1\",\n  \"images\": [\n    \"https://cdn.beatapi.io/samples/smart-bottle.png\"\n  ],\n  \"resolution\": \"2K\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Edit one image
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "model": "minimax-h3-image-highspeed",
  "prompt": "Keep the bottle exactly as it is. Replace the background with a sunlit kitchen counter and add a soft reflection under the bottle.",
  "aspect_ratio": "1:1",
  "images": ["https://cdn.beatapi.io/samples/smart-bottle.png"],
  "resolution": "2K"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.beatapi.io/v1/images/tasks")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Combine several images

**Request**

```json
{
  "model": "minimax-h3-image-highspeed",
  "prompt": "Place the bottle from the first image on a neon-lit stage like the one in the second image. Keep the bottle label readable.",
  "aspect_ratio": "16:9",
  "images": [
    "https://cdn.beatapi.io/samples/smart-bottle.png",
    "https://cdn.beatapi.io/samples/neon-singer.png"
  ],
  "resolution": "2K"
}
```

**Response**

```json
{
  "data": {
    "capability_id": "minimax-h3-image-highspeed",
    "capability_version": 1,
    "completed_at": null,
    "created_at": 1791993600,
    "error_code": null,
    "error_message": null,
    "id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
    "media_type": "image",
    "model": "minimax-h3-image-highspeed",
    "object": "task",
    "output": null,
    "poll_after_seconds": 5,
    "request_id": "req_5f0c2a9e4b7d4e31",
    "stage": "queued",
    "status": "queued",
    "task_kind": "image",
    "updated_at": 1791993600
  }
}
```

**SDK Code**

```python Combine several images
import requests

url = "https://api.beatapi.io/v1/images/tasks"

payload = {
    "model": "minimax-h3-image-highspeed",
    "prompt": "Place the bottle from the first image on a neon-lit stage like the one in the second image. Keep the bottle label readable.",
    "aspect_ratio": "16:9",
    "images": ["https://cdn.beatapi.io/samples/smart-bottle.png", "https://cdn.beatapi.io/samples/neon-singer.png"],
    "resolution": "2K"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Combine several images
const url = 'https://api.beatapi.io/v1/images/tasks';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"model":"minimax-h3-image-highspeed","prompt":"Place the bottle from the first image on a neon-lit stage like the one in the second image. Keep the bottle label readable.","aspect_ratio":"16:9","images":["https://cdn.beatapi.io/samples/smart-bottle.png","https://cdn.beatapi.io/samples/neon-singer.png"],"resolution":"2K"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Combine several images
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.beatapi.io/v1/images/tasks"

	payload := strings.NewReader("{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"Place the bottle from the first image on a neon-lit stage like the one in the second image. Keep the bottle label readable.\",\n  \"aspect_ratio\": \"16:9\",\n  \"images\": [\n    \"https://cdn.beatapi.io/samples/smart-bottle.png\",\n    \"https://cdn.beatapi.io/samples/neon-singer.png\"\n  ],\n  \"resolution\": \"2K\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Combine several images
require 'uri'
require 'net/http'

url = URI("https://api.beatapi.io/v1/images/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"Place the bottle from the first image on a neon-lit stage like the one in the second image. Keep the bottle label readable.\",\n  \"aspect_ratio\": \"16:9\",\n  \"images\": [\n    \"https://cdn.beatapi.io/samples/smart-bottle.png\",\n    \"https://cdn.beatapi.io/samples/neon-singer.png\"\n  ],\n  \"resolution\": \"2K\"\n}"

response = http.request(request)
puts response.read_body
```

```java Combine several images
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.beatapi.io/v1/images/tasks")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"Place the bottle from the first image on a neon-lit stage like the one in the second image. Keep the bottle label readable.\",\n  \"aspect_ratio\": \"16:9\",\n  \"images\": [\n    \"https://cdn.beatapi.io/samples/smart-bottle.png\",\n    \"https://cdn.beatapi.io/samples/neon-singer.png\"\n  ],\n  \"resolution\": \"2K\"\n}")
  .asString();
```

```php Combine several images
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.beatapi.io/v1/images/tasks', [
  'body' => '{
  "model": "minimax-h3-image-highspeed",
  "prompt": "Place the bottle from the first image on a neon-lit stage like the one in the second image. Keep the bottle label readable.",
  "aspect_ratio": "16:9",
  "images": [
    "https://cdn.beatapi.io/samples/smart-bottle.png",
    "https://cdn.beatapi.io/samples/neon-singer.png"
  ],
  "resolution": "2K"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Combine several images
using RestSharp;

var client = new RestClient("https://api.beatapi.io/v1/images/tasks");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"Place the bottle from the first image on a neon-lit stage like the one in the second image. Keep the bottle label readable.\",\n  \"aspect_ratio\": \"16:9\",\n  \"images\": [\n    \"https://cdn.beatapi.io/samples/smart-bottle.png\",\n    \"https://cdn.beatapi.io/samples/neon-singer.png\"\n  ],\n  \"resolution\": \"2K\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Combine several images
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "model": "minimax-h3-image-highspeed",
  "prompt": "Place the bottle from the first image on a neon-lit stage like the one in the second image. Keep the bottle label readable.",
  "aspect_ratio": "16:9",
  "images": ["https://cdn.beatapi.io/samples/smart-bottle.png", "https://cdn.beatapi.io/samples/neon-singer.png"],
  "resolution": "2K"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.beatapi.io/v1/images/tasks")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Exact size

**Request**

```json
{
  "model": "minimax-h3-image-highspeed",
  "prompt": "A flat illustration of a lighthouse on a cliff at dawn, pastel colours, clean shapes",
  "output_format": "webp",
  "size": "2720x1536"
}
```

**Response**

```json
{
  "data": {
    "capability_id": "minimax-h3-image-highspeed",
    "capability_version": 1,
    "completed_at": null,
    "created_at": 1791993600,
    "error_code": null,
    "error_message": null,
    "id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
    "media_type": "image",
    "model": "minimax-h3-image-highspeed",
    "object": "task",
    "output": null,
    "poll_after_seconds": 5,
    "request_id": "req_5f0c2a9e4b7d4e31",
    "stage": "queued",
    "status": "queued",
    "task_kind": "image",
    "updated_at": 1791993600
  }
}
```

**SDK Code**

```python Exact size
import requests

url = "https://api.beatapi.io/v1/images/tasks"

payload = {
    "model": "minimax-h3-image-highspeed",
    "prompt": "A flat illustration of a lighthouse on a cliff at dawn, pastel colours, clean shapes",
    "output_format": "webp",
    "size": "2720x1536"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Exact size
const url = 'https://api.beatapi.io/v1/images/tasks';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"model":"minimax-h3-image-highspeed","prompt":"A flat illustration of a lighthouse on a cliff at dawn, pastel colours, clean shapes","output_format":"webp","size":"2720x1536"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Exact size
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.beatapi.io/v1/images/tasks"

	payload := strings.NewReader("{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A flat illustration of a lighthouse on a cliff at dawn, pastel colours, clean shapes\",\n  \"output_format\": \"webp\",\n  \"size\": \"2720x1536\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Exact size
require 'uri'
require 'net/http'

url = URI("https://api.beatapi.io/v1/images/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A flat illustration of a lighthouse on a cliff at dawn, pastel colours, clean shapes\",\n  \"output_format\": \"webp\",\n  \"size\": \"2720x1536\"\n}"

response = http.request(request)
puts response.read_body
```

```java Exact size
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.beatapi.io/v1/images/tasks")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A flat illustration of a lighthouse on a cliff at dawn, pastel colours, clean shapes\",\n  \"output_format\": \"webp\",\n  \"size\": \"2720x1536\"\n}")
  .asString();
```

```php Exact size
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.beatapi.io/v1/images/tasks', [
  'body' => '{
  "model": "minimax-h3-image-highspeed",
  "prompt": "A flat illustration of a lighthouse on a cliff at dawn, pastel colours, clean shapes",
  "output_format": "webp",
  "size": "2720x1536"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Exact size
using RestSharp;

var client = new RestClient("https://api.beatapi.io/v1/images/tasks");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"model\": \"minimax-h3-image-highspeed\",\n  \"prompt\": \"A flat illustration of a lighthouse on a cliff at dawn, pastel colours, clean shapes\",\n  \"output_format\": \"webp\",\n  \"size\": \"2720x1536\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Exact size
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "model": "minimax-h3-image-highspeed",
  "prompt": "A flat illustration of a lighthouse on a cliff at dawn, pastel colours, clean shapes",
  "output_format": "webp",
  "size": "2720x1536"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.beatapi.io/v1/images/tasks")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```