GraphQL AI Image Mutations

PagibleAI’s image mutations generate and transform images through authenticated GraphQL requests. They return base64-encoded image data; they do not create or publish a CMS File automatically.

Use PagibleAI GraphQL API for session and CSRF setup. Use GraphQL Files when you want to store, protect and publish a generated result.

Generate an image

imagine creates an image from a text prompt and can use up to ten stored file UUIDs as visual references.

mutation Imagine(
  $prompt: String!
  $context: String
  $files: [String!]
) {
  imagine(prompt: $prompt, context: $context, files: $files)
}
{
  "prompt": "A compact electric bicycle parked beside a city café",
  "context": "Editorial product image, soft morning light",
  "files": ["018f2567-8508-7a62-9309-41708fbfe5fa"]
}

imagine arguments

Argument
Type
Limit
prompt
String!
Required, at most 2,000 characters
context
String
Accepted up to 2,000 characters; not used by the current resolver
files
[String!]
At most 10 file UUIDs; each at most 36 characters

The result is String containing base64 image data. Referenced files also require file:view permission. The current resolver does not apply context, so include essential visual instructions in prompt.

Upload images for editing

Editing mutations accept Upload! values through the GraphQL multipart request specification. Send null in the operations JSON for each upload variable and map each multipart binary field to its variable path.

Edit an image with curl

After logging in with the overview workflow, reuse the authenticated cookie jar. This request removes an image background with isolate:

BASE='https://your-domain.example'
ENCODED=$(awk '$6 == "XSRF-TOKEN" {print $7}' cms.cookies | tail -1)
TOKEN=$(php -r 'echo urldecode($argv[1]);' "$ENCODED")

curl --silent --show-error \
  --cookie cms.cookies \
  --cookie-jar cms.cookies \
  --header 'Accept: application/json' \
  --header "X-XSRF-TOKEN: $TOKEN" \
  --form 'operations={"query":"mutation Isolate($file: Upload!) { isolate(file: $file) }","variables":{"file":null}}' \
  --form 'map={"0":["variables.file"]}' \
  --form '0=@./product.jpg;type=image/jpeg' \
  "$BASE/graphql"
{
  "data": {
    "isolate": "iVBORw0KGgoAAAANSUhEUgAA..."
  }
}

Repaint a whole image

mutation Repaint($file: Upload!, $prompt: String!) {
  repaint(file: $file, prompt: $prompt)
}

Use repaint for changes that may affect the whole uploaded image. prompt is limited to 2,000 characters. Required capability: image:repaint.

Replace a masked area

mutation Inpaint($file: Upload!, $mask: Upload!, $prompt: String!) {
  inpaint(file: $file, mask: $mask, prompt: $prompt)
}

inpaint edits the area selected by the mask according to the prompt. The prompt is limited to 2,000 characters. Required capability: image:inpaint.

Erase a masked area

mutation Erase($file: Upload!, $mask: Upload!) {
  erase(file: $file, mask: $mask)
}

For erase, black mask pixels are kept and white pixels mark the area to remove. The provider fills the removed area from its surroundings. Required capability: image:erase.

Remove the background

mutation Isolate($file: Upload!) {
  isolate(file: $file)
}

isolate removes the background and returns base64 image data with transparency when the output format supports it. Required capability: image:isolate.

Extend an image

mutation Uncrop(
  $file: Upload!
  $top: Int!
  $right: Int
  $bottom: Int
  $left: Int
) {
  uncrop(
    file: $file
    top: $top
    right: $right
    bottom: $bottom
    left: $left
  )
}

uncrop outpaints beyond the existing boundaries. top is required; each side accepts 0 to 4,096 pixels. Required capability: image:uncrop.

Upscale an image

mutation Upscale($file: Upload!, $factor: Int!) {
  upscale(file: $file, factor: $factor)
}

factor must be an integer from 2 through 4. Required capability: image:upscale.

Handle the returned image

function detectImageMime(base64) {
  const bytes = Uint8Array.from(
    atob(base64.slice(0, 24)),
    character => character.charCodeAt(0),
  );

  if (bytes[0] === 0x89 && bytes[1] === 0x50) return 'image/png';
  if (bytes[0] === 0xff && bytes[1] === 0xd8) return 'image/jpeg';
  if (bytes[0] === 0x47 && bytes[1] === 0x49) return 'image/gif';
  if (String.fromCharCode(...bytes.slice(0, 4)) === 'RIFF' &&
      String.fromCharCode(...bytes.slice(8, 12)) === 'WEBP') return 'image/webp';

  return 'application/octet-stream';
}

const base64 = result.data.isolate;
const bytes = Uint8Array.from(
  atob(base64),
  character => character.charCodeAt(0),
);
const blob = new Blob([bytes], {type: detectImageMime(base64)});
const previewUrl = URL.createObjectURL(blob);

The GraphQL response does not include a MIME field. Detect the common image signatures as shown above or use the output format guaranteed by your configured provider. Reject application/octet-stream instead of presenting unknown binary data. To keep the result in the CMS, upload the Blob with addFile, review its detected MIME type and publish it separately.

Validation and errors

Uploaded images and masks are checked against the configured size and MIME policies. Provider failures, invalid arguments and missing capabilities appear in the GraphQL errors array. Image operations can take longer than normal content queries, so use a client timeout appropriate for your configured AI timeout.

{
  "errors": [
    {
      "message": "Image type \"application/pdf\" is not allowed",
      "path": ["isolate"]
    }
  ],
  "data": {
    "isolate": null
  }
}

Troubleshoot AI image mutations

Common AI image problems

Symptom
Likely cause
Resolution
Upload variable is null
The multipart map targets the wrong path
Map each binary field to its exact variable
Image or mask type is not allowed
The upload is not an allowed image MIME type
Check the actual binary and upload policy
Image exceeds the maximum size
Bytes or decoded pixels exceed configuration
Resize or compress before upload
Unexpected mask result
The mask polarity or dimensions are wrong
Match source dimensions and follow the operation’s black/white rule
Insufficient permissions
The user lacks the image capability or file:view
Inspect me.permission and referenced-file access
Provider request failed
Model, credentials, quota or upstream service failed
Check server-side AI configuration and logs
Unknown output type
The mutation returns base64 without MIME metadata
Detect the signature or use the provider’s guaranteed format
Result is not in the media library
AI mutations return data only
Convert to an upload, call addFile and publish separately