Custom Providers
Custom providers let you connect any third-party image or video generation API to Flokan — not just the built-in providers (OpenAI, Anthropic, Google AI, etc.). Paste the provider's docs, Flokan auto-configures the integration, and the provider becomes available everywhere AI generation is used (Image Editor, Thumbnail Generator, VO to Images).
Watch: custom provider setup walkthrough
This page is a reference for the most common provider configurations the community has already verified. If your provider is on this list, you can copy the configuration below directly into the Advanced section of the custom provider form instead of pasting raw docs.
Why these samples exist. Every time a Flokan user successfully tests a custom provider, that configuration is added to a verified library. The samples below are the most-used and admin-curated entries from that library — so you can be confident they actually work.
Quick reference — which sample matches your provider?
| Provider | Type | Pattern | Sample |
|---|---|---|---|
OpenAI (gpt-image-1) | Image gen + edit | Sync JSON | Jump ↓ |
| Google Gemini (image-preview) | Image gen | Sync JSON (Gemini format) | Jump ↓ |
| GenAIPro / GenAIPro VN | Image + Video | Async multipart | Jump ↓ |
GeminiGen (nano-banana-pro) | Image gen | Async multipart | Jump ↓ |
| GeminiGen Video (Veo / Grok / Seedance) | Video gen | Async multipart | Jump ↓ |
69 Labs (imagen-4) | Image gen | Async w/ download URL | Jump ↓ |
69 Labs Video (grok-imagine-video) | Video gen | Async w/ download URL | Jump ↓ |
| Leonardo.ai | Image gen | Async JSON | Jump ↓ |
kie.ai (nano-banana-2) | Image gen | Async JSON | Jump ↓ |
| Google Veo 2 (Generative Language) | Video gen | Async w/ query-string auth | Jump ↓ |
If your provider isn't on the list, follow the setup walkthrough and paste its docs — Flokan's AI will configure it for you. After your first successful test, your config is automatically added to the library so the next user gets it instantly.
Setup walkthrough
- Open Settings → AI Providers → Custom Provider → Add Custom Provider.
- Paste the section of the provider's API docs that covers image (or video) generation. Include the endpoint URL, request body, auth header format, and response format.
- Click Auto-Configure from Docs. Flokan parses the docs and pre-fills every field.
- Review the configuration. Click Advanced — Edit Configuration to inspect or override individual fields.
- Click Save Configuration, then add one or more API keys for the provider. Keys are encrypted with AES-256 and round-robined across requests.
If auto-configure can't detect an endpoint URL, the Advanced section opens automatically and you can fill it in manually — that's when these sample configurations become useful.
How to fill the form from your provider's docs
Most of the time you don't fill anything in. Paste your provider's docs, click Auto-Configure, and Flokan fills the form for you. Use this section only when auto-configure missed something and you need to complete it by hand.
Every image API — no matter the provider — gives you the same handful of facts. Your job is to find each fact in the provider's docs and copy it into the matching box in the Advanced section. Here's what to look for, in plain language:
The 5 things you always need
| Find this in the provider's docs… | …and put it in this box | What it looks like |
|---|---|---|
| The web address you send the request to | Endpoint URL | a line starting with https:// (often labelled POST) |
| How the provider checks your key | Auth Header + Auth Format | "Send your key in the Authorization header as Bearer YOUR_KEY" |
| The example request body | Request Body Template | the JSON block under "Request" or "Body" |
| Where the picture comes back in the response | Response Image Path | trace the response example down to the image — see below |
| Whether the response is a link or raw image data | Response Format | a URL (url) or a long base64 string (base64) |
That's the whole job. Everything else in the form has a sensible default you can leave alone.
Step by step
-
Open the provider's API docs and find the section titled something like "Generate an image" or "Create image". Ignore everything else on their site.
-
Endpoint URL — copy the
https://…address they tell you to send the request to. If you seePOST https://api.example.com/v1/images, you only copy thehttps://…part. -
Auth Header + Auth Format — find the sentence about your API key. The two most common cases:
- "Pass your key as
Authorization: Bearer <key>" → Auth Header =Authorization, Auth Format =Bearer {{api_key}} - "Send your key in the
x-api-keyheader" → Auth Header =x-api-key, Auth Format ={{api_key}}
Wherever the docs show your real key, you type
{{api_key}}instead. Flokan swaps in the real key for you. - "Pass your key as
-
Request Body Template — copy the example JSON request body from the docs into this box. Then find the line that holds the prompt text and replace it with
{{prompt}}. For example, the docs show"prompt": "a cat on a sofa"— you change it to"prompt": "{{prompt}}". (Click the blue variable pills under the box to copy{{prompt}}and the others.) -
Response Image Path — this is the only field that looks technical, so here's the trick. Look at the provider's example response, then write the path from the top down to the image, joining each step with a dot. Use
[0]for "the first item in a list."The provider's example response:
{ "data": [ { "url": "https://.../image.png" } ] }To read the path: start at the top, step into
data, take the first item with[0], then step into itsurl. Join the steps with dots:data[0].url -
Response Format — if the image came back as a web link (like the example above), choose URL. If it came back as a very long string of letters and numbers (a
b64_json/ base64 field), choose base64. -
Leave the rest alone. Provider Name is just a label. Model ID is optional. Reference Image Format defaults to Presigned URL, which works for most providers. Click Save Configuration, add your API key, and run a test.
Is my provider "async"? (the one extra case)
Most providers return the image immediately. Some take longer, so instead of the picture they first send back a job ID, and you have to check back ("poll") until it's ready. If the provider's docs mention a "job ID," "task ID," "status," or a separate endpoint to check progress, turn on the Async switch and fill in:
| Box | What to find in the docs |
|---|---|
| Job ID Path | where the ID lives in the first response (e.g. id, data.taskId) |
| Poll Endpoint URL | the "check status" web address, with {{job_id}} where the ID goes |
| Status Path | where the status word lives in the check-status response (e.g. status) |
| Done Value | the word that means "ready" (e.g. completed, success, COMPLETED) |
| Result Image Path | where the finished image link lives once it's done |
The sample configurations below show real examples of both styles — find one shaped like your provider and copy its values.
Stuck on a 400 / 401 error after saving? Jump to Troubleshooting — it lists the exact box to fix for each error.
Field reference
These are the fields you'll see in the Advanced section. Every sample below maps each value to one of these fields.
| Field | What it does |
|---|---|
| Provider Name | Friendly name shown in the AI Providers list |
| Auth Header | HTTP header that carries the API key — usually Authorization or x-api-key |
| Auth Format | How the key is wrapped. Bearer {{api_key}} is standard. {{api_key}} sends the raw key. |
| Endpoint URL | The image-generation endpoint (must be https://) |
| Model ID | The provider's model identifier (e.g. gpt-image-1, imagen-4) |
| Request Body Template | JSON body with placeholders like {{prompt}}, {{reference_images_urls}}, {{aspect_ratio}} |
| Request Content Type | application/json (default) or multipart/form-data (when the provider requires file uploads) |
| Response Image Path | Dot-path to the image in the response, e.g. data[0].b64_json |
| Response Format | base64 or url |
| Reference Image Format | How Flokan sends reference images — presigned_url (default), proxy_url, or base64 |
| Async toggle | Enable for providers that return a job ID and require polling |
| Job ID Path | Where the job ID lives in the submit response (e.g. data.taskId, id, uuid) |
| Poll Endpoint URL | The status endpoint, with {{job_id}} as a placeholder |
| Status Path | Dot-path to the status field in the poll response |
| Done Value | The value of the status field that means "ready" (e.g. completed, success, COMPLETED, 2) |
| Result Path | Dot-path to the result image/video URL in the poll response |
Available variables (request templates)
Image: {{prompt}}, {{reference_images_urls}}, {{reference_images_base64}}, {{reference_images_data_urls}}, {{source_image_url}}, {{source_image_base64}}, {{aspect_ratio}}, {{width}}, {{height}}, {{api_key}}
Video: {{prompt}}, {{motion_prompt}}, {{source_image_url}}, {{source_image_base64}}, {{duration_seconds}}, {{resolution}}, {{api_key}}
Click any variable pill in the form to copy it.
Sample configurations
OpenAI (gpt-image-1)
OpenAI's image API. Sync JSON, base64 response. Supports both generation and editing.
Provider Name: OpenAI Images
Auth Header: Authorization
Auth Format: Bearer {{api_key}}
# Image generation
Endpoint URL: https://api.openai.com/v1/images/generations
Model ID: gpt-image-1
Request Content Type: application/json
Response Format: base64
Response Image Path: data[0].b64_json
Async: offGeneration request template:
{
"n": 1,
"size": "1024x1024",
"model": "gpt-image-1",
"prompt": "{{prompt}}"
}Image-editing endpoint:
Edit Endpoint URL: https://api.openai.com/v1/images/edits
Edit Model: gpt-image-1
Edit Response Format: base64
Edit Response Image Path: data[0].b64_jsonEdit request template:
{
"n": 1,
"size": "1024x1024",
"model": "gpt-image-1",
"images": ["{{source_image_url}}"],
"prompt": "{{prompt}}"
}Google Gemini (image-preview)
Google's Gemini image generation. Sync JSON, base64 response. Note the unusual x-goog-api-key header and the nested parts structure.
Provider Name: Gemini Image
Auth Header: x-goog-api-key
Auth Format: {{api_key}}
Endpoint URL: https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent
Model ID: gemini-3.1-flash-image-preview
Request Content Type: application/json
Response Format: base64
Response Image Path: candidates[0].content.parts[0].inlineData.data
Async: offRequest template:
{
"tools": [{ "google_search": {} }],
"contents": [
{
"parts": [
{ "text": "{{prompt}}" }
]
}
],
"generationConfig": {
"imageConfig": { "aspectRatio": "16:9" },
"responseModalities": ["TEXT", "IMAGE"]
}
}GenAIPro / GenAIPro VN
Async image generation via multipart form-data. Submit → poll. Same provider on two hosts (genaipro.io and genaipro.vn).
Provider Name: GenAIPro
Auth Header: Authorization
Auth Format: Bearer {{api_key}}
# Image generation (async)
Endpoint URL: https://genaipro.io/api/v2/veo/create-image
Request Content Type: multipart/form-data
Response Format: url
Async: on
Job ID Path: id
Poll Endpoint URL: https://genaipro.io/api/v2/veo/tasks/{{job_id}}
Status Path: status
Done Value: completed
Result Path: file_urls[0]Image request template:
{
"model": "nano_banana_2",
"prompt": "{{prompt}}",
"aspect_ratio": "IMAGE_ASPECT_RATIO_LANDSCAPE",
"number_of_images": "1",
"reference_images": "{{reference_images_urls}}"
}Video endpoint (also supported on the same provider):
Video Endpoint URL: https://genaipro.io/api/v2/veo/text-to-video
Video Response Format: url
Video Response Path: file_urls[0]Video request template:
{
"prompt": "{{prompt}}",
"aspect_ratio": "VIDEO_ASPECT_RATIO_LANDSCAPE",
"number_of_videos": 1,
"upscale_resolution": "none"
}GenAIPro requires multipart/form-data for image requests. If you switch to JSON the API will return 400.
GeminiGen — Nano Banana Pro (image)
Async image generation. Uses the x-api-key header (raw key, not Bearer). Done value is "2" (numeric string).
Provider Name: GeminiGen
Auth Header: x-api-key
Auth Format: {{api_key}}
Endpoint URL: https://api.geminigen.ai/uapi/v1/generate_image
Model ID: nano-banana-pro
Request Content Type: multipart/form-data
Response Format: url
Async: on
Job ID Path: uuid
Poll Endpoint URL: https://api.geminigen.ai/uapi/v1/history/{{job_id}}
Status Path: status
Done Value: 2
Result Path: generated_image[0].image_urlRequest template:
{
"model": "nano-banana-pro",
"style": "Photorealistic",
"prompt": "{{prompt}}",
"resolution": "1K",
"file_urls[]": "{{reference_images_urls}}",
"aspect_ratio": "16:9",
"output_format": "jpeg"
}GeminiGen — Video (Veo / Grok / Seedance)
GeminiGen exposes multiple async video models on the same auth + polling pattern. Swap the video_endpoint_url, model, and request template for the model you want.
Shared config:
Auth Header: x-api-key
Auth Format: {{api_key}}
Video Request Content Type: multipart/form-data
Video Async: on
Job ID Path: uuid
Poll Endpoint URL: https://api.geminigen.ai/uapi/v1/history/{{job_id}}
Status Path: status
Done Value: 2
Result Path: generated_video[0].video_url
Video Response Format: urlGrok-3 (image-to-video):
Video Endpoint URL: https://api.geminigen.ai/uapi/v1/video-gen/grok
Model: grok-3{
"mode": "normal",
"model": "grok-3",
"prompt": "{{prompt}}",
"duration": 10,
"resolution": "720p",
"file_urls[]": "{{source_image_url}}",
"aspect_ratio": "landscape"
}Veo-2 (text-to-video):
Video Endpoint URL: https://api.geminigen.ai/uapi/v1/video-gen/veo
Model: veo-2{
"model": "veo-2",
"prompt": "{{prompt}}",
"mode_image": "frame",
"resolution": "720p",
"aspect_ratio": "16:9"
}Seedance-2-Omni:
Video Endpoint URL: https://api.geminigen.ai/uapi/v1/video-gen/seedance
Model: seedance-2-omni{
"mode": "pro",
"model": "seedance-2-omni",
"prompt": "{{prompt}}",
"duration": "{{duration_seconds}}",
"aspect_ratio": "16:9"
}69 Labs — Imagen-4 (image)
Async image generation. The submit response only contains the job ID — the image bytes are fetched from a separate download URL after polling reports COMPLETED. This uses the Result URL Template field (advanced).
Provider Name: 69 Labs
Auth Header: Authorization
Auth Format: Bearer {{api_key}}
Endpoint URL: https://69labs.vip/api/v1/images/generate
Model ID: imagen-4
Reference Image Format: proxy_url # 69labs rejects presigned URLs with query-string auth
Response Format: url
Response Image Path: id # submit response returns just the job id
Async: on
Job ID Path: id
Poll Endpoint URL: https://69labs.vip/api/v1/images/status/{{job_id}}
Status Path: status
Done Value: COMPLETED
Result URL Template: https://69labs.vip/api/v1/images/download/{{job_id}}Request template:
{
"model": "imagen-4",
"prompt": "{{prompt}}",
"imageUrls": "{{reference_images_urls}}",
"aspectRatio": "{{aspect_ratio}}"
}69 Labs validates reference image URLs strictly and rejects presigned URLs (query-string auth). You must set Reference Image Format → Public proxy URL in the form.
69 Labs — Video
Same pattern as the image endpoint, but for video. Submit → poll → download from a constructed URL.
Provider Name: 69 Labs Video
Auth Header: Authorization
Auth Format: Bearer {{api_key}}
Video Endpoint URL: https://69labs.vip/api/v1/videos/generate
Video Model: grok-imagine-video
Video Response Format: url
Video Response Path: id
Video Async: on
Video Job ID Path: id
Video Poll Endpoint: https://69labs.vip/api/v1/videos/status/{{job_id}}
Video Status Path: status
Video Done Value: COMPLETED
Video Result URL Template: https://69labs.vip/api/v1/videos/download/{{job_id}}Video request template:
{
"model": "grok-imagine-video",
"prompt": "{{prompt}}",
"imageUrls": "{{reference_images_urls}}",
"aspectRatio": "{{aspect_ratio}}"
}Leonardo.ai
Async image generation, JSON body. The job ID lives in a nested path in the submit response (generate.generationId).
Provider Name: Leonardo
Auth Header: Authorization
Auth Format: Bearer {{api_key}}
Endpoint URL: https://cloud.leonardo.ai/api/rest/v2/generations
Model ID: nano-banana-2
Request Content Type: application/json
Response Format: url
Async: on
Job ID Path: generate.generationId
Poll Endpoint URL: https://cloud.leonardo.ai/api/rest/v1/generations/{{job_id}}
Status Path: generations_by_pk.status
Done Value: COMPLETE
Result Path: generations_by_pk.generated_images[0].urlRequest template:
{
"model": "nano-banana-2",
"public": false,
"parameters": {
"width": 1024,
"height": 1024,
"prompt": "{{prompt}}",
"quantity": 1,
"prompt_enhance": "OFF"
}
}kie.ai (nano-banana-2)
Async image generation, JSON body. Polling URL uses a query string for the task ID instead of a path segment.
Provider Name: kie.ai
Auth Header: Authorization
Auth Format: Bearer {{api_key}}
Endpoint URL: https://api.kie.ai/api/v1/jobs/createTask
Model ID: nano-banana-2
Request Content Type: application/json
Response Format: url
Async: on
Job ID Path: data.taskId
Poll Endpoint URL: https://api.kie.ai/api/v1/jobs/recordInfo?taskId={{job_id}}
Status Path: data.state
Done Value: success
Result Path: data.resultJson.resultUrls[0]Request template:
{
"model": "nano-banana-2",
"input": {
"prompt": "{{prompt}}",
"resolution": "1K",
"image_input": [],
"aspect_ratio": "16:9",
"output_format": "png"
}
}Google Veo 2 (Generative Language API)
Async video. Uses query-string auth (?key={{api_key}}) instead of a header — the API key is embedded in both the submit URL and the poll URL.
Provider Name: Google Veo 2
Auth Header: Authorization # unused; key is in the URL
Auth Format: Bearer {{api_key}}
Video Endpoint URL: https://generativelanguage.googleapis.com/v1beta/models/veo-2.0-generate-001:predictLongRunning?key={{api_key}}
Video Async: on
Video Job ID Path: name
Video Poll Endpoint: https://generativelanguage.googleapis.com/v1beta/{{job_id}}?key={{api_key}}
Video Status Path: done
Video Done Value: true
Video Result Path: response.generateVideoResponse.generatedSamples[0].video.uri
Video Response Format: urlVideo request template:
{
"instances": [
{
"image": {
"mimeType": "image/png",
"bytesBase64Encoded": "{{source_image_base64}}"
},
"prompt": "{{prompt}}"
}
],
"parameters": {
"aspectRatio": "16:9",
"personGeneration": "allow_adult"
}
}The job ID (name) returned by Veo 2 is a full path like models/veo-2.0-generate-001/operations/abc123. Flokan substitutes that directly into the poll URL — no path manipulation needed.
Troubleshooting
"Endpoint URL could not be detected" — Auto-configure didn't find a URL in the pasted docs. Open Advanced and enter the endpoint URL manually. The sample configurations above will help you fill the other fields.
"No valid response image path" — The Response Image Path doesn't match the actual response structure. Make a test request in the provider's playground (or via curl), copy the response, and trace the dot-path to the image data.
Test returns 400 — Most often this is a content-type mismatch. If the provider's docs show Content-Type: multipart/form-data or describe file uploads, switch Request Content Type to multipart/form-data in the Advanced section.
Test returns 401 / 403 — Auth header or format is wrong. Common variations:
Authorization: Bearer {{api_key}}(OpenAI, Anthropic, most providers)x-api-key: {{api_key}}(GeminiGen)X-API-Key: {{api_key}}(capitalization matters for some providers)x-goog-api-key: {{api_key}}(Google Generative Language)?key={{api_key}}in the URL (Google Veo 2)
Reference images don't reach the provider — Try Reference Image Format → Public proxy URL in Advanced. Some providers reject presigned URLs because they include query-string auth (e.g. 69 Labs).
Async job never finishes — Check the Done Value. Providers use very different values: completed, success, COMPLETED, COMPLETE, true, 2. The exact string from the polling response matters.
Related
- AI Providers (BYOK) — Connect built-in providers (OpenAI, Anthropic, Google AI, etc.)
- VO to Images — The pipeline that uses these providers
- Image Editor — Single-image editing with any configured provider