Generate imagesLarge Language ModelsVisual Effects

Free Image Generation API for n8n: Workflow and Setup

A hands-on setup for generating images from n8n with a free API. Create the token, store it as a credential, build the POST, Wait and Switch polling loop, save the file, and keep batches under the five-job limit so bulk runs finish without errors.

Free Image Generation API for n8n: Workflow and Setup
Cristian Da Conceicao
Founder of Picasso IA

You can wire a free image generation API into n8n in about twenty minutes, and the part that trips people up is not the request. It is the waiting. Image jobs on the PicassoIA API are asynchronous, so a single HTTP Request node hands you a job ID instead of a picture, and everything after that depends on how well you poll, retry and save the result. This walkthrough builds the whole loop: a trigger, a prompt, a POST that creates the prediction, a Wait and IF pair that polls until the job finishes, and a download step that turns the output into a real file inside your workflow.

A developer's hands on a laptop beside a coffee mug in morning light

If you have used the Replicate API before, you will feel at home. If you have not, that is fine too: every call in this article is shown with the exact URL, header and body you need, plus the n8n expressions that glue the nodes together.

What the API Gives You

PicassoIA exposes a developer API that behaves like the Replicate prediction API. You create a job, you poll it, you read the output. There is no streaming and no webhook callback to configure, which is actually good news for n8n, because polling is something the editor does very well.

An open notebook with a hand-drawn flow of five connected boxes on a wooden desk

Endpoints and models

The base URL is https://api.picassoia.com/v1, and every request carries a bearer token that starts with pia_sk_. Four endpoints handle the whole lifecycle of a job:

ActionMethod and pathWhat you use it for
Create a jobPOST /v1/models/{owner}/{name}/predictionsStart one generation
Check a jobGET /v1/predictions/{id}Poll the status and read the output
Cancel a jobPOST /v1/predictions/{id}/cancelStop a job you no longer need
List jobsGET /v1/predictionsAudit recent runs

For still images, two models matter. picassoia/picassoia-image is the text-to-image model, documented on the PicassoIA Image page. It is unlimited, supports seven aspect ratios, accepts a seed, and outputs JPG, PNG or WebP. picassoia/picassoia-image-editor-pro handles edits to existing pictures, and lives at PicassoIA Image Editor Pro. Two video models sit behind the same endpoint style, which becomes useful once your image workflow is stable and you want motion from the same trigger.

Limits worth knowing

Before you design anything, write these numbers on a sticky note:

  • 5 concurrent predictions per account, shared across every token and every MCP connection you own
  • 4,000 characters maximum per prompt
  • 10 MB maximum request body
  • 3 hours before a job times out
  • 2 API tokens maximum per account

The concurrency cap shapes your workflow more than anything else. We will come back to it in the failures section, because a spreadsheet with 200 rows will blow past five jobs in about two seconds if you let it.

💡 Check your plan before you promise "free" to a client. The API pages say predictions are currently free and use no credits, but the documentation also mentions an Infinite plan for API access, and the pricing page lists API access on several tiers. Those statements do not line up perfectly, so confirm what your own account allows before you build a client deliverable on it.

How to Use PicassoIA Image

Run your prompt in the browser first. It costs nothing, takes ten seconds, and tells you whether the wording is right before you spend an afternoon debugging nodes.

A woman in a knit sweater looking at a laptop in a home office

  1. Open the PicassoIA Image model page and sign in.
  2. Write your prompt like a photographer, not like a search query. Name the subject, the setting, the light and the lens. "Ceramic mug on linen, window light from the left, 50mm, shallow depth of field" beats "nice mug picture".
  3. Choose the aspect ratio. Use 16:9 for blog headers, 1:1 for product tiles and 9:16 for stories and vertical ads.
  4. Pick the output format. JPG is the default, WebP gives smaller files, PNG keeps every pixel.
  5. Decide how many images you want per run (one or two). Once a result looks right, lock the seed so you can reproduce it.
  6. Generate, then write down every setting you used. Those exact names go into the API body later.

The browser fields map one to one to the request body, so nothing gets lost in translation:

FieldDefaultNotes
promptnone (required)Plain-language description, up to 4,000 characters
aspect_ratio1:1Also 16:9, 9:16, 4:3, 3:4, 3:2, 2:3
seedrandomInteger, set it for repeatable output
output_formatjpgjpg, png or webp
output_quality800 to 100, applies to JPG and WebP only
num_outputs1One or two images per call

💡 Writing forty prompts by hand gets old fast. Draft variations in a chat model such as GPT 5 Mini or Claude 4.5 Haiku, keep the best ones, and paste them into the spreadsheet your workflow reads from.

Set Up the n8n Credential

Most failed setups die here, not in the workflow. Spend two minutes on this and you will not think about authentication again.

Create the API token

Open the API page in your PicassoIA account and create a token. It will start with pia_sk_. Copy it immediately into a password manager. Because an account holds at most two tokens, use one for production n8n and keep the second for local testing, so you can revoke either without breaking the other.

A closed brass padlock on a weathered oak door

Test it from a terminal before n8n gets involved:

curl -s -X POST https://api.picassoia.com/v1/models/picassoia/picassoia-image/predictions \
  -H "Authorization: Bearer $PICASSOIA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"input":{"prompt":"Ceramic mug on linen, window light from the left, 50mm","aspect_ratio":"16:9"}}'

A JSON response with an id means the token works. Poll it with GET https://api.picassoia.com/v1/predictions/<id> until the status reads succeeded, then look at the shape of the output field. You will need that shape in a minute.

Store it in n8n

In n8n, open Credentials, create a new Header Auth credential and fill it in like this:

  • Name: Authorization
  • Value: Bearer pia_sk_ followed by your token, with a single space after "Bearer"
  • Credential name: PicassoIA API

Never paste the token into a Set node or straight into an HTTP Request field. It ends up in execution logs and in any workflow you export or share. A saved credential stays out of both. On a self-hosted instance you can also inject it through an environment variable, but the credential store is simpler and enough for most teams.

The Workflow, Node by Node

Here is the full shape. Eight nodes, one loop:

#NodeIts job
1Schedule Trigger or WebhookStarts the run
2Edit Fields (Set)Holds prompt, aspect ratio and format
3HTTP Request (POST)Creates the prediction
4WaitPauses a few seconds
5HTTP Request (GET)Reads the job status
6Switch or IFRoutes on succeeded, failed or "still running"
7HTTP Request (GET, file)Downloads the finished image
8Drive, S3 or Write FilesStores it where you need it

A developer at a standing desk looking at a monitor with connected workflow blocks

Trigger and prompt node

Start with a Schedule Trigger if the work is routine, or a Webhook if another tool should be able to ask for images. Follow it with an Edit Fields node that sets three string fields: prompt, aspect_ratio and output_format. Keeping them in one node means you change a setting once, not in five places.

Create the prediction

Add an HTTP Request node and name it Create prediction. Set the method to POST and the URL to https://api.picassoia.com/v1/models/picassoia/picassoia-image/predictions. Under authentication choose Generic Credential Type, then Header Auth, then your PicassoIA API credential. Switch Send Body on, choose JSON, and use this body:

{
  "input": {
    "prompt": "{{ $json.prompt }}",
    "aspect_ratio": "{{ $json.aspect_ratio }}",
    "output_format": "{{ $json.output_format }}",
    "num_outputs": 1
  }
}

If your prompts can contain quotation marks or line breaks, build the body as an expression instead: {{ JSON.stringify({ input: { prompt: $json.prompt, aspect_ratio: $json.aspect_ratio, output_format: $json.output_format, num_outputs: 1 } }) }}. That one change prevents the classic "invalid JSON" error on prompts like a sign that says "OPEN".

The response includes the job id. That is the only value the rest of the workflow really needs.

Wait and poll

Add a Wait node set to resume after a time interval, five seconds to start. Then a second HTTP Request node named Check prediction with the method GET and this URL:

https://api.picassoia.com/v1/predictions/{{ $('Create prediction').item.json.id }}

Feed the result into a Switch node that reads {{ $json.status }} and sends succeeded to the download step, failed to your error branch, and everything else back into the Wait node. That backward connection is your loop.

A glass hourglass with sand falling on a wooden desk

Two habits keep the loop safe. First, count attempts. A small Code node that increments an attempts field and stops at 30 will rescue you from a job that never resolves. Second, do not poll faster than the work takes. Images finish quickly, so a three to five second interval is plenty, and hammering the status endpoint every half second only burns executions.

Download the image

Now the output. Add a third HTTP Request node, method GET, with the URL set to the image address from the finished job. For a single output that is usually {{ $json.output[0] }}, but run the loop once with a test prompt and check the shape in the execution panel before you trust that expression. In the node's Options, add Response, set Response Format to File and leave the binary property as data.

From here the image is a normal n8n binary file. Send it to Google Drive, S3, a WordPress media endpoint, Slack or a local folder. Save the file itself rather than the result link, so your archive never depends on a URL staying alive.

Handle Failures and Limits

A workflow that works once is a demo. A workflow that survives 200 rows on a Monday morning is a tool. The difference is mostly in this section.

An aerial view of a toll plaza with five open lanes and one car in each

Stay under five concurrent jobs

Here is the trap. The POST call returns in a fraction of a second, so an HTTP Request node fed with 50 rows will start 50 jobs almost instantly, long before the first one finishes. Only five can run at once, and the rest will be rejected or queued depending on how the API responds.

The fix is a Loop Over Items node with the batch size set to 5, placed before the create step. Each batch creates five jobs, polls them until all five are done, saves the files, and only then loops back for the next five. Remember that the limit is shared across your whole account, including MCP connections. If a colleague is generating images through a connected assistant at the same time, you share the same five slots.

Retry failed predictions

A failed status is not always your fault. Route it to a short Wait (ten seconds works), then send the same prompt once more. If the second attempt also fails, stop retrying and notify someone through the Slack, Gmail or Telegram node. Retrying forever just hides a bad prompt.

For plain network hiccups, open the HTTP Request node's Settings tab and turn on Retry On Fail with three tries and a two second pause. That handles dropped connections without touching your loop logic.

Prompt length and request size

Prompts are capped at 4,000 characters. If your prompts come from user input or from a language model, trim them in a Code node with $json.prompt.slice(0, 4000) before they reach the API. The 10 MB body limit will not bother you for text-only image generation, but it matters once you start sending source pictures to the editor model.

A tired man in his forties squinting at a laptop late in the evening

When something breaks anyway, this table lists the usual suspects:

SymptomLikely causeFix
401 UnauthorizedMissing Bearer prefix or a wrong tokenRe-enter the credential value as Bearer pia_sk_...
Jobs rejected in bulk runsMore than 5 predictions at onceLoop Over Items with a batch size of 5
output[0] is undefinedOutput read before the status was succeededRoute only the succeeded branch to the download node
Download node returns JSONResponse Format left on the defaultSet Response Format to File
Prompt rejectedMore than 4,000 charactersTrim the prompt in a Code node
Workflow never endsNo cap on polling attemptsStop after 30 polls and alert someone

Exact error codes come from the API itself, so open the failed execution and read the response body before guessing.

Three Workflows Worth Building

The same loop powers very different jobs. Swap the trigger and the destination, keep the middle.

Three handmade ceramic mugs in sage, cream and terracotta on a linen cloth

Blog headers on a schedule

Point a Schedule Trigger at a Google Sheets node that returns rows marked todo. Build the prompt from the article title plus a fixed style line: "documentary photograph, natural light, 35mm, no text". Generate at 16:9, upload to your media library, and write the file URL back to the row with the status done. An editor can queue twenty titles in the evening and find twenty headers waiting in the morning.

Product shots from a spreadsheet

One row per product, with columns for the product name, material and setting. Generate at 1:1, set num_outputs to 2 so you can pick the better frame, and keep one seed per product line so the lighting stays consistent across a catalog. For shots that need an existing photo adjusted rather than invented, send that photo through the PicassoIA Image Editor Pro model with a second HTTP Request node. Check its model page for the exact input fields it expects.

Social posts from a webhook

Let a form, a Slack command or another workflow call your Webhook node with a short brief. Use the Respond to Webhook node to answer right away with "got it", then run the generation in the background and post the finished 9:16 image to the channel when the job succeeds. People stay happy because nothing hangs while the image renders.

Pick the Right Model

At the time of writing, the API exposes four models: two for images and two for video. For your n8n workflow the image pair is the whole decision.

ModelBest forWhere it fits in n8n
PicassoIA ImageNew images from a prompt, unlimited runsThe default Create prediction node
PicassoIA Image Editor ProChanging or fixing a photo you already haveA second branch that receives a source image

The rest of the catalog is still useful, just not through the API today. Models like P Image and FLUX Schnell are worth testing in the browser to compare styles, and the platform also offers background removal, upscaling and a large library of video effects through its all models page. A practical pattern: try a look in the browser, then reproduce the winning prompt and seed in n8n.

Run Your First Image Today

You now have everything for a working loop: a token stored safely, a POST that creates the job, a Wait and Switch that poll it, a File download that saves the result, and batches of five that respect the concurrency limit. The fastest way to prove it is to keep the first version tiny. One Edit Fields node, one prompt, no spreadsheet, no loop over items. When that single image lands in your folder, add the batches and the schedule.

Open PicassoIA Image in your browser, write a prompt about something you actually need this week, and generate it. Then copy that exact prompt, aspect ratio and seed into the n8n workflow above. Try a 16:9 header, a square product tile and a vertical story from the same prompt, and see which one your team reaches for first. Everything you test is one click away on Picasso IA, so the only thing left is to press run.

Share this article