ioy.ai
Sign inGet the starter
Product guide

AI workflows: chat, images and answers with sources

Configure and use private conversations, image editing, captions and web search with shared credits and recovery.

What can the reference application do?

The studio includes writing, image generation, speech, image editing, image captions and answers with web sources. The Chat page saves private conversations and includes earlier successful turns in each new answer. Every workflow uses the same account, credits, task history and result recovery.

The hosted template website does not run paid model calls. Install or generate your own project, configure the selected providers and verify an actual result before advertising that feature.

How do I try it locally?

  1. Follow local setup, including npm run db:local to apply the conversation migration.
  2. Create and verify an account using the local mail viewer.
  3. In the studio, select an image workflow and upload a PNG, JPEG or WebP reference up to 8 MiB. Each upload belongs to your account and uses the configured file retention period.
  4. Select Chat, create a conversation and send two messages. The second response reports that it received earlier context.
  5. Select Web search. The local fixture shows a clearly labeled fixed answer with a documentation source; no search request is made.

Local text, images, speech, conversations and search results are marked as simulations. These prove the account, storage and credit flow; they do not prove a model's output quality.

Which providers can I select?

AI_PROVIDERS_JSON maps enabled feature IDs to server-side adapters. Omitted entries use the OpenAI compatible provider. Chat and search can inherit the text provider; image editing can inherit image.

{
  "text": "workers-ai",
  "chat": "workers-ai",
  "image": "fal",
  "image-edit": "fal",
  "image-caption": "openai",
  "web-search": "workers-ai",
  "audio": "openai"
}
Adapter Supported workflows Required configuration
OpenAI compatible Writing, chat, captions, image generation, image editing, speech OPENAI_API_KEY; optional HTTPS OPENAI_BASE_URL; TEXT_MODEL, IMAGE_MODEL, AUDIO_MODEL, optional SEARCH_MODEL
Workers AI Writing, chat, captions, image generation, search answer synthesis Wrangler AI binding; optional WORKERS_TEXT_MODEL, WORKERS_IMAGE_MODEL, WORKERS_VISION_MODEL
fal Image generation and image editing FAL_API_KEY; optional FAL_IMAGE_MODEL, FAL_EDIT_MODEL
Brave Search Web retrieval before answer synthesis BRAVE_SEARCH_API_KEY; selected text provider and model cost configuration

Use npx wrangler secret put KEY_NAME for every secret. Never place keys in product requirements, browser code, public Skill files or Git.

For Workers AI, add this binding to the generated project's Wrangler configuration:

"ai": { "binding": "AI" }

Defaults are @cf/meta/llama-3.1-8b-instruct-fp8 for text, @cf/black-forest-labs/flux-1-schnell for images, and @cf/meta/llama-3.2-11b-vision-instruct for captions. The vision model requires the account owner to accept Meta's license and acceptable use policy before first use. Complete that provider step yourself; the template does not accept legal terms automatically. Check the official Workers AI model catalog for current availability and terms.

The fal defaults are fal-ai/flux/dev and fal-ai/flux-kontext/dev. Editing sends the reference as a server-side data URI. Your R2 bucket and reference files remain private. Review the selected provider's data retention policy before processing user images.

How are costs and credits calculated?

Product credits come from app/core/product.ts, including the charge for each chat turn. Model costs come from MODEL_COSTS_JSON. Configure rates for each selected model using current provider prices, a source URL and the date checked. Image models use perImage; text and caption models use inputPerMillion and outputPerMillion; speech uses perSecond.

Web search requires a separate rate entry:

"brave-web-search": {
  "perRequest": 0.005,
  "source": "replace with your verified plan pricing URL",
  "updatedAt": "2026-10-12"
}

The value above is a configuration example, not a current price promise. Replace it with your actual plan rate. The combined search cost includes retrieval and model synthesis. Free plan rates require freeProvider: true.

The system reserves credits before calling the provider. Successful tasks settle once. Confirmed failures release once. Unknown paid outcomes keep their reservation while the task is reconciled. Chat estimates include the stored context; image caption estimates include an allowance for the reference image. Cost records are estimates unless a verified invoice or provider usage proves the final amount.

How does a conversation retain context?

A conversation is scoped to its user. Up to 12 previous successful turns are considered, keeping complete question/answer pairs within a 24,000-character prompt budget. Each task stores the context it actually used. Failed or unfinished answers are not silently used as successful history.

Only one active or unknown turn may exist in a conversation. Wait for the saved task before sending the next message. Rename or delete a conversation from the Chat page. Deleting removes its conversation context; the original task and metering record remain in task history. Account export and deletion include conversations.

What happens when a provider call is interrupted?

The studio and Chat page save the operation key and known task ID in your session. Reopening checks the saved task before sending another request. A retried operation key returns the original task and never charges it twice.

For fal, the request ID and model endpoint are persisted before polling. If a result remains queued or a connection breaks, maintenance reads that exact request's status and output. It does not submit another image request. OpenAI compatible and Workers AI outcomes without a durable provider receipt need result receipt recovery or an operator's verified reconciliation. An unknown result is never guessed to be successful.

How do I use the API?

Use a scoped API key with jobs:read, jobs:write, and, for images, files:read / files:write as needed. Create a conversation, then send a message with a stable idempotency key:

curl "$SAAS_API_URL/api/v1/conversations" \
  -H "Authorization: Bearer $SAAS_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"title":"My product idea"}'

curl "$SAAS_API_URL/api/v1/conversations/CONVERSATION_ID/messages" \
  -H "Authorization: Bearer $SAAS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: first-message-operation' \
  -d '{"prompt":"Help me choose the first useful workflow."}'

Upload a private reference using POST /api/v1/files with raw image bytes, its correct Content-Type, and a stable Idempotency-Key. If it returns pending, query /api/v1/files/{id}/metadata before creating a task. Retry the same file and key to recover its original object; changed contents, MIME or name conflict. Use the returned ID as inputAssetId in an image-edit or image-caption task. web-search tasks return sources with titles and URLs. See API reference and /openapi.json for exact schemas and the generated client.

Search snippets are treated as untrusted data. The template does not fetch arbitrary result URLs or let their instructions run tools. Source links show the evidence retrieved; a model answer still needs appropriate review.