Skip to content

AI Provider Service

The AI Provider Service (zship-provider1-service) exists to solve two problems:

  1. Integration: Beyond core node10-ai, it unifies external image / video / TTS APIs (KIE, WaveSpeed, …) behind one gateway — same auth, credits, and task model — so your product code does not sprawl with multiple SDKs and signing styles.
  2. Operations: Async generation (callbacks, retries, refunds) is hard to run without admin tools. Testing, task logs, analytics, gallery, rate limits, and blocks are there so you can validate config, answer support, read usage, and enforce policy without shipping app releases for every change.

ProviderAPITypical capabilities
KIEapi.kie.aiImage (nano-banana-2, Seedream), video (Kling, Wan), TTS (ElevenLabs), and more
WaveSpeed AIapi.wavespeed.aiImage (nano-banana-2), video (Wan 2.6), editing, LoRA, and more

Why: One place to manage multiple vendors — swap models or vendors mostly by configuration, not by branching product code.


CapabilityWhy we built it
No-code onboardingAdd models, change mapping or validation without a new web/admin release — shorter iteration and safer rollbacks when a model is misbehaving.
CreditsTied to node1-auth so every task has traceable spend — easier refunds, reconciliation, and disputes.
Webhooks & R2Most providers are async; standard callbacks and file offload let dashboards and lists show stable results instead of every client inventing URLs.
Config-driven mappingAbsorb vendor-specific JSON (mapping, templates, strip lists) inside the gateway so the app sends business fields only.

Admin — KIE / WaveSpeed AI providers


ToolWhy we built it
Dry runValidate payload, mapping, validation, and credit estimate with no upstream call and no charge — catch misconfiguration before it burns credits in production.
Live testProve API keys, callback base URL, and connectivity with real HTTP; does not debit end-user credits — safe for destructive debugging.
Status lookupAsync jobs often stall in IN_PROGRESS; fetch by task id to see whether the bottleneck is upstream slowness, lost webhooks, or mapping bugs.
Webhook debuggingWrong callback URLs look like “tasks never finish”; dedicated checks cut callback integration time sharply.

Takeaway: Separate “is the config correct?” from “are we charging real users while experimenting?”


Task & log management (Providers → Tasks)

Section titled “Task & log management (Providers → Tasks)”
ToolWhy we built it
Searchable listSupport can find a run by email, task id, model, … without grepping raw application logs.
Per-task detail (stored requests/responses)Keeps user payload, upstream request/response, errors, and credits for disputes, audits, and engineering repro (sensitive fields may be redacted by role).
RetryTransient upstream/network failures are cheaper to replay the same request than asking users to click again; also verifies “after fixing config, does the same job succeed?”.

Takeaway: Observability for async pipelines — without it you only see “failed”, not where it failed.


ViewWhy we built it
OverviewTotals, success/fail/in-flight, credits, distinct users — capacity and cost at a glance.
By providerSee which vendor is expensive, slow, or flaky — data for model choices and targeted throttling.
Filter by app_keySplit usage by project or tenant for billing, limits, and account reviews.

Takeaway: Move from “it runs” to “we know how it runs and where money goes”.


Section titled “Public gallery (Providers → Gallery + public GET /gallery)”
ToolWhy we built it
User opt-in publicSeparates shareable outputs from private generations — fewer privacy incidents.
Public list APIMarketing / campaign pages can show curated results in a grid without exposing R2 as a flat public file dump.
Moderation & featuredCommunity surfaces need policy review and editorial slots for campaigns and social proof.

Takeaway: Turn raw task output into marketable, community-facing assets.


ControlWhy we built it
Rate limits (scoped)Protect upstream quotas and your credit economy from scripted abuse; per-key / per-provider / global scopes with 429 and retry hints.
API key blocksWhen keys are stolen or misused, revoke at the gateway (per provider or wildcard) faster than code deploys.
IP & edge (Cloudflare)The service enforces who uses which key; IP/geo/bot rules belong on Cloudflare WAF / custom rules and stack with the controls above.

Takeaway: Keep an open API usable while bounding cost and abuse risk.


Content moderation runs before a generation request is sent to KIE, WaveSpeed, or another generation provider. It checks only the configured request fields and normalizes the upstream response to allow, deny, flag, error, or skipped.

  1. Deploy versions of zship-provider1-service and Admin that include content moderation.
  2. Run pnpm db:migrate:remote from backend/zship-provider1-service. Confirm that 0015_content_moderation.sql and 0016_content_moderation_field_rules.sql have been applied.
  3. Create a dedicated API key in the moderation vendor’s console. Do not reuse a generation-provider key unless the vendor explicitly issues the same credential, and never put the key in frontend code or documentation.
  1. Open Admin → Providers → Content moderation.
  2. Select the project scope. All projects (default) is the wildcard fallback; an enabled configuration for a specific app_key takes precedence.
  3. Select the moderation provider, verify the prefilled HTTPS endpoint, and enter the API key and timeout. Keep moderation disabled while testing.
  4. Configure the default prompt fields and any provider/model-specific overrides.
  5. Choose whether to charge the user, then configure failure and flag behavior.
  6. Save the configuration. In the Provider test panel, test both clearly safe and clearly disallowed prompts. Tests call the real moderation API but do not debit end-user credits.
  7. Enable moderation only after the tests pass, then monitor decisions, latency, status codes, and credits under Recent decisions.
ProviderDefault API endpointAuthentication and behavior
Creem Screen Prompthttps://api.creem.io/v1/moderation/promptUses a Creem API key and returns a synchronous result.
WaveSpeed Content Moderatorhttps://api.wavespeed.ai/api/v3/wavespeed-ai/content-moderator/textUses a WaveSpeed API key; the gateway handles submission, polling, and output retrieval.

Keep the default endpoint unless the vendor explicitly requires another production endpoint. Endpoints must use HTTPS, and the timeout must be between 1,000 and 30,000 ms.

Default prompt fields are comma-separated field paths, for example:

prompt, text, negative_prompt, input.prompt

Dots address nested object properties. String values are included directly; arrays of strings are included item by item, with duplicate text removed. If none of the configured fields are present, the result is skipped: no moderation request is sent and no moderation credits are charged.

When generation providers or models use different request shapes, add a provider/model field override. Field selection uses this precedence:

  1. Exact generation provider + model rule
  2. Generation-provider default rule (model left empty)
  3. Default prompt fields

For example, if one KIE model reads input.prompt while a WaveSpeed model reads prompt, configure separate rules instead of sending both fields unconditionally.

Setting / resultRuntime behavior
allowPasses moderation and continues to the generation request.
denyAlways blocks generation with CONTENT_MODERATION_BLOCKED.
flagBlocks when Block flagged prompts is enabled; otherwise generation continues.
errorContinues when Fail open is enabled; otherwise returns CONTENT_MODERATION_UNAVAILABLE.
skippedNo configured field was found, so moderation is not called and generation continues.
Charge userWhen a moderation API call was attempted, charges the configured credits per check. Admin tests never debit user credits.

Moderation and generation are billed separately. Once a moderation call has occurred, its credits are retained even if the prompt is blocked or the later generation fails. Only generation credits follow the normal generation-refund path. This separation applies to prepaid and enterprise billing. Before enabling user charges, verify the vendor’s per-call price, your credit conversion, and the desired insufficient-balance experience.

Recent decisions store operational metadata such as request ID, project, user, generation provider, moderation provider, decision, reason, prompt length, status code, duration, and credits. The prompt text itself is not stored. The selected text is still sent to the configured third-party moderation provider, so review the vendor’s privacy, data residency, and retention terms before production use.

  • Save before testing: the test panel uses the API key, endpoint, and timeout stored in the database.
  • API key required when enabling: enter a valid key and save. Existing keys may appear masked in read-only or redacted views.
  • A model checks the wrong fields: confirm that the generation provider key and model ID exactly match Providers configuration, and look for a higher-priority exact rule.
  • Many results are skipped: the configured paths do not match the actual generation request body.
  • The moderation vendor is intermittently unavailable: inspect response codes and latency, adjust the timeout, and decide whether fail-open matches your risk policy.
  • The user was charged but generation failed: this is expected for a completed moderation attempt; generation credits follow their own refund path while moderation credits are retained.

Contact us to purchase the AI Provider Service. After purchase:

  1. Deploy backend/zship-provider1-service to Cloudflare
  2. Point admin’s PROVIDER1_SERVICE binding at your Worker
  3. Configure providers (KIE, WaveSpeed, …) under Admin → Providers
  • Providers (/providers) — config, content moderation, tasks, stats, gallery, rate limits, blocks
  • Provider test (/providers-test) — dry run, live test, status, webhook checks